diff --git a/orderer/common/msgprocessor/maintenancefilter.go b/orderer/common/msgprocessor/maintenancefilter.go
index 3da2957ada7..29ddef9f0b3 100644
--- a/orderer/common/msgprocessor/maintenancefilter.go
+++ b/orderer/common/msgprocessor/maintenancefilter.go
@@ -8,9 +8,8 @@ package msgprocessor
 
 import (
 	"bytes"
-	"time"
+	"github.com/hyperledger/fabric/orderer/consensus/smartbft/util"
 
-	"github.com/SmartBFT-Go/consensus/pkg/types"
 	"github.com/golang/protobuf/proto"
 	cb "github.com/hyperledger/fabric-protos-go/common"
 	"github.com/hyperledger/fabric-protos-go/orderer"
@@ -141,7 +140,7 @@ func (mf *MaintenanceFilter) inspect(configEnvelope *cb.ConfigEnvelope, ordererC
 				return errors.Wrap(err, "failed to unmarshal BFT metadata configuration")
 			}
 
-			_, err := validateBFTMetadataOptions(1, updatedMetadata)
+			_, err := util.ConfigFromMetadataOptions(1, updatedMetadata)
 			if err != nil {
 				return errors.New("invalid BFT metadata configuration")
 			}
@@ -210,62 +209,6 @@ func (mf *MaintenanceFilter) ensureConsensusTypeChangeOnly(configEnvelope *cb.Co
 	return nil
 }
 
-func validateBFTMetadataOptions(selfID uint64, options *smartbft.Options) (types.Configuration, error) {
-	var err error
-
-	config := types.DefaultConfig
-	config.SelfID = selfID
-
-	if options == nil {
-		return config, errors.New("config metadata options field is nil")
-	}
-
-	config.RequestBatchMaxCount = options.RequestBatchMaxCount
-	config.RequestBatchMaxBytes = options.RequestBatchMaxBytes
-	if config.RequestBatchMaxInterval, err = time.ParseDuration(options.RequestBatchMaxInterval); err != nil {
-		return config, errors.Wrap(err, "bad config metadata option RequestBatchMaxInterval")
-	}
-	config.IncomingMessageBufferSize = options.IncomingMessageBufferSize
-	config.RequestPoolSize = options.RequestPoolSize
-	if config.RequestForwardTimeout, err = time.ParseDuration(options.RequestForwardTimeout); err != nil {
-		return config, errors.Wrap(err, "bad config metadata option RequestForwardTimeout")
-	}
-	if config.RequestComplainTimeout, err = time.ParseDuration(options.RequestComplainTimeout); err != nil {
-		return config, errors.Wrap(err, "bad config metadata option RequestComplainTimeout")
-	}
-	if config.RequestAutoRemoveTimeout, err = time.ParseDuration(options.RequestAutoRemoveTimeout); err != nil {
-		return config, errors.Wrap(err, "bad config metadata option RequestAutoRemoveTimeout")
-	}
-	if config.ViewChangeResendInterval, err = time.ParseDuration(options.ViewChangeResendInterval); err != nil {
-		return config, errors.Wrap(err, "bad config metadata option ViewChangeResendInterval")
-	}
-	if config.ViewChangeTimeout, err = time.ParseDuration(options.ViewChangeTimeout); err != nil {
-		return config, errors.Wrap(err, "bad config metadata option ViewChangeTimeout")
-	}
-	if config.LeaderHeartbeatTimeout, err = time.ParseDuration(options.LeaderHeartbeatTimeout); err != nil {
-		return config, errors.Wrap(err, "bad config metadata option LeaderHeartbeatTimeout")
-	}
-	config.LeaderHeartbeatCount = options.LeaderHeartbeatCount
-	if config.CollectTimeout, err = time.ParseDuration(options.CollectTimeout); err != nil {
-		return config, errors.Wrap(err, "bad config metadata option CollectTimeout")
-	}
-	config.SyncOnStart = options.SyncOnStart
-	config.SpeedUpViewChange = options.SpeedUpViewChange
-
-	config.LeaderRotation = false
-	config.DecisionsPerLeader = 0
-
-	if err = config.Validate(); err != nil {
-		return config, errors.Wrap(err, "config validation failed")
-	}
-
-	if options.RequestMaxBytes == 0 {
-		config.RequestMaxBytes = config.RequestBatchMaxBytes
-	}
-
-	return config, nil
-}
-
 func validateBFTConsenterMapping(currentOrdererConfig channelconfig.Orderer, nextOrdererConfig channelconfig.Orderer) error {
 	// extract raft consenters from consensusTypeValue.metadata
 	raftMetadata := &etcdraft.ConfigMetadata{}
diff --git a/orderer/consensus/smartbft/consenter.go b/orderer/consensus/smartbft/consenter.go
index 0b8bc12763c..6c60b072f76 100644
--- a/orderer/consensus/smartbft/consenter.go
+++ b/orderer/consensus/smartbft/consenter.go
@@ -188,7 +188,7 @@ func (c *Consenter) HandleChain(support consensus.ConsenterSupport, metadata *cb
 		c.Logger.Panicf("Failed initializing block puller")
 	}
 
-	config, err := configFromMetadataOptions((uint64)(selfID), configOptions)
+	config, err := ConfigFromMetadataOptions((uint64)(selfID), configOptions)
 	if err != nil {
 		return nil, errors.Wrap(err, "failed parsing smartbft configuration")
 	}
diff --git a/orderer/consensus/smartbft/util.go b/orderer/consensus/smartbft/util.go
index e2bf9779c69..65e5351078b 100644
--- a/orderer/consensus/smartbft/util.go
+++ b/orderer/consensus/smartbft/util.go
@@ -13,9 +13,6 @@ import (
 	"encoding/hex"
 	"encoding/pem"
 	"fmt"
-	"sort"
-	"time"
-
 	"github.com/SmartBFT-Go/consensus/pkg/types"
 	"github.com/SmartBFT-Go/consensus/smartbftprotos"
 	"github.com/golang/protobuf/proto"
@@ -30,8 +27,10 @@ import (
 	"github.com/hyperledger/fabric/orderer/common/localconfig"
 	"github.com/hyperledger/fabric/orderer/consensus"
 	"github.com/hyperledger/fabric/orderer/consensus/etcdraft"
+	"github.com/hyperledger/fabric/orderer/consensus/smartbft/util"
 	"github.com/hyperledger/fabric/protoutil"
 	"github.com/pkg/errors"
+	"sort"
 )
 
 // RuntimeConfig defines the configuration of the consensus
@@ -119,7 +118,7 @@ func configBlockToBFTConfig(selfID uint64, block *cb.Block, bccsp bccsp.BCCSP) (
 		return types.Configuration{}, err
 	}
 
-	return configFromMetadataOptions(selfID, consensusConfigOptions)
+	return util.ConfigFromMetadataOptions(selfID, consensusConfigOptions)
 }
 
 //go:generate counterfeiter -o mocks/mock_blockpuller.go . BlockPuller
@@ -189,62 +188,6 @@ func getViewMetadataFromBlock(block *cb.Block) (*smartbftprotos.ViewMetadata, er
 	return &viewMetadata, nil
 }
 
-func configFromMetadataOptions(selfID uint64, options *smartbft.Options) (types.Configuration, error) {
-	var err error
-
-	config := types.DefaultConfig
-	config.SelfID = selfID
-
-	if options == nil {
-		return config, errors.New("config metadata options field is nil")
-	}
-
-	config.RequestBatchMaxCount = options.RequestBatchMaxCount
-	config.RequestBatchMaxBytes = options.RequestBatchMaxBytes
-	if config.RequestBatchMaxInterval, err = time.ParseDuration(options.RequestBatchMaxInterval); err != nil {
-		return config, errors.Wrap(err, "bad config metadata option RequestBatchMaxInterval")
-	}
-	config.IncomingMessageBufferSize = options.IncomingMessageBufferSize
-	config.RequestPoolSize = options.RequestPoolSize
-	if config.RequestForwardTimeout, err = time.ParseDuration(options.RequestForwardTimeout); err != nil {
-		return config, errors.Wrap(err, "bad config metadata option RequestForwardTimeout")
-	}
-	if config.RequestComplainTimeout, err = time.ParseDuration(options.RequestComplainTimeout); err != nil {
-		return config, errors.Wrap(err, "bad config metadata option RequestComplainTimeout")
-	}
-	if config.RequestAutoRemoveTimeout, err = time.ParseDuration(options.RequestAutoRemoveTimeout); err != nil {
-		return config, errors.Wrap(err, "bad config metadata option RequestAutoRemoveTimeout")
-	}
-	if config.ViewChangeResendInterval, err = time.ParseDuration(options.ViewChangeResendInterval); err != nil {
-		return config, errors.Wrap(err, "bad config metadata option ViewChangeResendInterval")
-	}
-	if config.ViewChangeTimeout, err = time.ParseDuration(options.ViewChangeTimeout); err != nil {
-		return config, errors.Wrap(err, "bad config metadata option ViewChangeTimeout")
-	}
-	if config.LeaderHeartbeatTimeout, err = time.ParseDuration(options.LeaderHeartbeatTimeout); err != nil {
-		return config, errors.Wrap(err, "bad config metadata option LeaderHeartbeatTimeout")
-	}
-	config.LeaderHeartbeatCount = options.LeaderHeartbeatCount
-	if config.CollectTimeout, err = time.ParseDuration(options.CollectTimeout); err != nil {
-		return config, errors.Wrap(err, "bad config metadata option CollectTimeout")
-	}
-	config.SyncOnStart = options.SyncOnStart
-	config.SpeedUpViewChange = options.SpeedUpViewChange
-
-	config.LeaderRotation = false
-	config.DecisionsPerLeader = 0
-
-	if err = config.Validate(); err != nil {
-		return config, errors.Wrap(err, "config validation failed")
-	}
-
-	if options.RequestMaxBytes == 0 {
-		config.RequestMaxBytes = config.RequestBatchMaxBytes
-	}
-
-	return config, nil
-}
-
 type request struct {
 	sigHdr   *cb.SignatureHeader
 	envelope *cb.Envelope
diff --git a/orderer/consensus/smartbft/util/util.go b/orderer/consensus/smartbft/util/util.go
new file mode 100644
index 00000000000..4d210b2a36d
--- /dev/null
+++ b/orderer/consensus/smartbft/util/util.go
@@ -0,0 +1,70 @@
+/*
+Copyright IBM Corp. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package util
+
+import (
+	"github.com/SmartBFT-Go/consensus/pkg/types"
+	"github.com/hyperledger/fabric-protos-go/orderer/smartbft"
+	"github.com/pkg/errors"
+	"time"
+)
+
+func ConfigFromMetadataOptions(selfID uint64, options *smartbft.Options) (types.Configuration, error) {
+	var err error
+
+	config := types.DefaultConfig
+	config.SelfID = selfID
+
+	if options == nil {
+		return config, errors.New("config metadata options field is nil")
+	}
+
+	config.RequestBatchMaxCount = options.RequestBatchMaxCount
+	config.RequestBatchMaxBytes = options.RequestBatchMaxBytes
+	if config.RequestBatchMaxInterval, err = time.ParseDuration(options.RequestBatchMaxInterval); err != nil {
+		return config, errors.Wrap(err, "bad config metadata option RequestBatchMaxInterval")
+	}
+	config.IncomingMessageBufferSize = options.IncomingMessageBufferSize
+	config.RequestPoolSize = options.RequestPoolSize
+	if config.RequestForwardTimeout, err = time.ParseDuration(options.RequestForwardTimeout); err != nil {
+		return config, errors.Wrap(err, "bad config metadata option RequestForwardTimeout")
+	}
+	if config.RequestComplainTimeout, err = time.ParseDuration(options.RequestComplainTimeout); err != nil {
+		return config, errors.Wrap(err, "bad config metadata option RequestComplainTimeout")
+	}
+	if config.RequestAutoRemoveTimeout, err = time.ParseDuration(options.RequestAutoRemoveTimeout); err != nil {
+		return config, errors.Wrap(err, "bad config metadata option RequestAutoRemoveTimeout")
+	}
+	if config.ViewChangeResendInterval, err = time.ParseDuration(options.ViewChangeResendInterval); err != nil {
+		return config, errors.Wrap(err, "bad config metadata option ViewChangeResendInterval")
+	}
+	if config.ViewChangeTimeout, err = time.ParseDuration(options.ViewChangeTimeout); err != nil {
+		return config, errors.Wrap(err, "bad config metadata option ViewChangeTimeout")
+	}
+	if config.LeaderHeartbeatTimeout, err = time.ParseDuration(options.LeaderHeartbeatTimeout); err != nil {
+		return config, errors.Wrap(err, "bad config metadata option LeaderHeartbeatTimeout")
+	}
+	config.LeaderHeartbeatCount = options.LeaderHeartbeatCount
+	if config.CollectTimeout, err = time.ParseDuration(options.CollectTimeout); err != nil {
+		return config, errors.Wrap(err, "bad config metadata option CollectTimeout")
+	}
+	config.SyncOnStart = options.SyncOnStart
+	config.SpeedUpViewChange = options.SpeedUpViewChange
+
+	config.LeaderRotation = false
+	config.DecisionsPerLeader = 0
+
+	if err = config.Validate(); err != nil {
+		return config, errors.Wrap(err, "config validation failed")
+	}
+
+	if options.RequestMaxBytes == 0 {
+		config.RequestMaxBytes = config.RequestBatchMaxBytes
+	}
+
+	return config, nil
+}