Skip to content

Commit

Permalink
code cleanup and updated quorum calculation
Browse files Browse the repository at this point in the history
Signed-off-by: Parameswaran Selvam <parselva@in.ibm.com>
  • Loading branch information
Param-S committed Feb 6, 2023
1 parent b0f03f0 commit 25cdcfd
Show file tree
Hide file tree
Showing 19 changed files with 296 additions and 774 deletions.
7 changes: 5 additions & 2 deletions common/channelconfig/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,9 @@ func MarshalEtcdRaftMetadata(md *etcdraft.ConfigMetadata) ([]byte, error) {

// MarshalBFTOptions serializes smartbft options.
func MarshalBFTOptions(op *smartbft.Options) ([]byte, error) {
copyMd := proto.Clone(op).(*smartbft.Options)
return proto.Marshal(copyMd)
if copyMd, ok := proto.Clone(op).(*smartbft.Options); ok {
return proto.Marshal(copyMd)
} else {
return nil, errors.New("consenter options type mismatch")
}
}
4 changes: 3 additions & 1 deletion common/policies/bft.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ SPDX-License-Identifier: Apache-2.0
package policies

import (
"math"

cb "github.com/hyperledger/fabric-protos-go/common"
mspa "github.com/hyperledger/fabric-protos-go/msp"
"github.com/hyperledger/fabric/common/policydsl"
Expand Down Expand Up @@ -36,7 +38,7 @@ func EncodeBFTBlockVerificationPolicy(consenterProtos []*cb.Consenter, ordererGr
}

sp := &cb.SignaturePolicyEnvelope{
Rule: policydsl.NOutOf(int32(2*f+1), pols),
Rule: policydsl.NOutOf(int32(math.Ceil(float64(n+f+1)/2)), pols),
Identities: identities,
}
ordererGroup.Policies[BlockValidationPolicyKey] = &cb.ConfigPolicy{
Expand Down
1 change: 0 additions & 1 deletion integration/nwo/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,4 @@ const CCEnvDefaultImage = "hyperledger/fabric-ccenv:latest"

var RequiredImages = []string{
CCEnvDefaultImage,
// runner.CouchDBDefaultImage,
}
50 changes: 6 additions & 44 deletions integration/smartbft/smartbft_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,6 @@ var _ = Describe("EndToEnd Smart BFT configuration test", func() {
By("Deploying chaincode")
deployChaincode(network, channel, testDir)

/* By("check block validation policy on app channel")
assertBlockValidationPolicy(network, peer, network.Orderers[0], channel, common.Policy_IMPLICIT_ORDERER) */

By("check peers are using the BFT delivery client")
// for _, peerRunner := range peerRunners {
// Eventually(peerRunner.Err(), network.EventuallyTimeout, time.Second).Should(gbytes.Say("Created BFT Delivery Client"))
// }

By("querying the chaincode")
sess, err := network.PeerUserSession(peer, "User1", commands.ChaincodeQuery{
ChannelID: channel,
Expand Down Expand Up @@ -243,10 +235,6 @@ var _ = Describe("EndToEnd Smart BFT configuration test", func() {
Expect(channelInfo).To(Equal(expectedChannelInfoPT))
}

/* assertBlockReception(map[string]int{"systemchannel": 0}, network.Orderers, peer, network)
By("check block validation policy on sys channel")
assertBlockValidationPolicy(network, peer, network.Orderers[0], "systemchannel", common.Policy_IMPLICIT_ORDERER) */

By("Waiting for followers to see the leader")
Eventually(ordererRunners[1].Err(), network.EventuallyTimeout, time.Second).Should(gbytes.Say("Message from 1"))
Eventually(ordererRunners[2].Err(), network.EventuallyTimeout, time.Second).Should(gbytes.Say("Message from 1"))
Expand All @@ -257,8 +245,6 @@ var _ = Describe("EndToEnd Smart BFT configuration test", func() {
orderer := network.Orderers[0]
network.JoinChannel(channel, orderer, network.PeersWithChannel(channel)...)

// assertBlockReception(map[string]int{"systemchannel": 1}, network.Orderers, peer, network)

nwo.DeployChaincode(network, channel, network.Orderers[0], nwo.Chaincode{
Name: "mycc",
Version: "0.0",
Expand All @@ -275,17 +261,12 @@ var _ = Describe("EndToEnd Smart BFT configuration test", func() {
By("Deployed chaincode successfully")
assertBlockReception(map[string]int{"testchannel1": 4}, network.Orderers, peer, network)

/* By("check block validation policy on app channel")
assertBlockValidationPolicy(network, peer, network.Orderers[0], channel, common.Policy_IMPLICIT_ORDERER)
*/

By("Transacting on testchannel1")
invokeQuery(network, peer, orderer, channel, 90)
invokeQuery(network, peer, orderer, channel, 80)
assertBlockReception(map[string]int{"testchannel1": 6}, network.Orderers, peer, network)

By("Adding a new consenter")

orderer5 := &nwo.Orderer{
Name: "orderer5",
Organization: "OrdererOrg",
Expand Down Expand Up @@ -315,14 +296,6 @@ var _ = Describe("EndToEnd Smart BFT configuration test", func() {
ordererIdentity, err := ioutil.ReadFile(network.OrdererCert(orderer5))
Expect(err).NotTo(HaveOccurred())

/* identity := protoutil.MarshalOrPanic(&msp.SerializedIdentity{
Mspid: "OrdererMSP",
IdBytes: ordererIdentity,
})
sanitizedIdentity, err := crypto.SanitizeIdentity(identity)
Expect(err).NotTo(HaveOccurred()) */

nwo.UpdateConsenters(network, peer, orderer, channel, func(orderers *common.Orderers) {
orderers.ConsenterMapping = append(orderers.ConsenterMapping, &common.Consenter{
MspId: "OrdererMSP",
Expand All @@ -334,26 +307,25 @@ var _ = Describe("EndToEnd Smart BFT configuration test", func() {
Port: uint32(network.OrdererPort(orderer5, nwo.ClusterPort)),
})
})

assertBlockReception(map[string]int{"testchannel1": 7}, network.Orderers[:4], peer, network)

By("Waiting for followers to see the leader")
Eventually(ordererRunners[0].Err(), network.EventuallyTimeout, time.Second).Should(gbytes.Say("Message from 3 channel=testchannel1"))
Eventually(ordererRunners[1].Err(), network.EventuallyTimeout, time.Second).Should(gbytes.Say("Message from 3 channel=testchannel1"))
Eventually(ordererRunners[3].Err(), network.EventuallyTimeout, time.Second).Should(gbytes.Say("Message from 3 channel=testchannel1"))

By("Planting last config block in the orderer's file system")
configBlock := nwo.GetConfigBlock(network, peer, orderer, "testchannel1")
Expect(configBlock).NotTo(Equal(nil))

By("Launching the added orderer")
By("Launching the added orderer: " + orderer5.Name)
orderer5Runner := network.OrdererRunner(orderer5)
orderer5Runner.Command.Env = append(orderer5Runner.Command.Env, "FABRIC_LOGGING_SPEC=grpc=debug:orderer.consensus.smartbft=debug:policies.ImplicitOrderer=debug")
ordererRunners = append(ordererRunners, orderer5Runner)
proc := ifrit.Invoke(orderer5Runner)
ordererProcesses = append(ordererProcesses, proc)
Eventually(proc.Ready(), network.EventuallyTimeout).Should(BeClosed())

By("Get latest config block")
configBlock := nwo.GetConfigBlock(network, peer, orderer, "testchannel1")
Expect(configBlock).NotTo(Equal(nil))

expectedChannelInfoPT = channelparticipation.ChannelInfo{
Name: "testchannel1",
URL: "/participation/v1/channels/testchannel1",
Expand All @@ -362,7 +334,7 @@ var _ = Describe("EndToEnd Smart BFT configuration test", func() {
Height: 0,
}

By("joining " + orderer5.Name + " to channel as a consenter")
By("Joining " + orderer5.Name + " to channel as a consenter")
channelparticipation.Join(network, orderer5, "testchannel1", configBlock, expectedChannelInfoPT)

By("Waiting for the added orderer to see the leader")
Expand All @@ -377,7 +349,6 @@ var _ = Describe("EndToEnd Smart BFT configuration test", func() {
}

channelInfo := channelparticipation.ListOne(network, orderer5, "testchannel1")
fmt.Printf("channelInfo: %+v\n", channelInfo)
Expect(channelInfo).To(Equal(expectedChannelInfoPT))

By("Make sure the peers get the config blocks, again")
Expand All @@ -404,7 +375,6 @@ var _ = Describe("EndToEnd Smart BFT configuration test", func() {
Eventually(ordererRunners[0].Err(), network.EventuallyTimeout, time.Second).Should(gbytes.Say("Changing to follower role, current view: 1, current leader: 2 channel=testchannel1"))

By("Making sure the previous leader synchronizes")
// Eventually(ordererRunners[0].Err(), network.EventuallyTimeout, time.Second).Should(gbytes.Say("Replicated decisions from view 0 and seq 7 up to view 0 and sequence 7 with verification sequence 0 channel=testchannel1"))
Eventually(ordererRunners[0].Err(), network.EventuallyTimeout, time.Second).Should(gbytes.Say("Starting view with number 1, sequence 8, and decisions 0 channel=testchannel1"))

By("Making sure previous leader sees the new leader")
Expand Down Expand Up @@ -592,11 +562,7 @@ var _ = Describe("EndToEnd Smart BFT configuration test", func() {
time.Sleep(time.Second * 2)
invokeQuery(network, peer, orderer, channel, 20)
time.Sleep(time.Second * 2)

// assertBlockReception(map[string]int{"testchannel1": 12}, network.Orderers, peer, network)

invokeQuery(network, peer, orderer, channel, 10)
// assertBlockReception(map[string]int{"testchannel1": 13}, network.Orderers, peer, network)

By("Submitting to orderer4")
invokeQuery(network, peer, network.Orderers[3], channel, 0)
Expand Down Expand Up @@ -930,7 +896,6 @@ var _ = Describe("EndToEnd Smart BFT configuration test", func() {
}

channelInfo := channelparticipation.ListOne(network, newOrderer, "testchannel1")
fmt.Printf("channelInfo: %+v\n", channelInfo)
Expect(channelInfo).To(Equal(expectedChannelInfoPT))

By("Ensure all orderers are in sync")
Expand Down Expand Up @@ -961,9 +926,6 @@ var _ = Describe("EndToEnd Smart BFT configuration test", func() {
})

assertBlockReception(map[string]int{"testchannel1": 8 + i}, network.Orderers[i+1:], peer, network)

/* By(fmt.Sprintf("Make sure the peers are up to date with the orderers and have height of %d", 8+i))
waitForBlockReceptionByPeer(peer, network, channel, uint64(8+i)) */
}
})

Expand Down
2 changes: 1 addition & 1 deletion internal/configtxgen/encoder/encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ func NewOrdererGroup(conf *genesisconfig.Orderer) (*cb.ConfigGroup, error) {
}
addValue(ordererGroup, channelconfig.OrderersValue(consenterProtos), channelconfig.AdminsPolicyKey)
if consensusMetadata, err = channelconfig.MarshalBFTOptions(conf.SmartBFT); err != nil {
return nil, errors.Errorf("cannot marshal metadata for orderer type %s: %s", ConsensusTypeBFT, err)
return nil, errors.Errorf("consenter options read failed with error %s for orderer type %s", err, ConsensusTypeBFT)
}
// Overwrite policy manually by computing it from the consenters
policies.EncodeBFTBlockVerificationPolicy(consenterProtos, ordererGroup)
Expand Down
50 changes: 0 additions & 50 deletions orderer/common/multichannel/ledger_resources_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,56 +71,6 @@ func (mrm *mutableResourcesMock) CreateBundle(channelID string, c *common.Config
return mockResources, nil
}

// func TestLedgerResources_VerifyBlockSignature(t *testing.T) {
// mockResources := &mocks.Resources{}
// mockValidator := &mocks.ConfigTXValidator{}
// mockValidator.ChannelIDReturns("mychannel")
// mockResources.ConfigtxValidatorReturns(mockValidator)

// mockPolicy := &mocks.Policy{}
// mockPolicyManager := &mocks.PolicyManager{}
// mockResources.PolicyManagerReturns(mockPolicyManager)

// ms := &mutableResourcesMock{
// Resources: mockResources,
// }
// cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
// require.NoError(t, err)
// cs := &ChainSupport{
// ledgerResources: &ledgerResources{
// configResources: &configResources{
// mutableResources: ms,
// bccsp: cryptoProvider,
// },
// },
// BCCSP: cryptoProvider,
// }

// // Scenario I: Policy manager isn't initialized
// // and thus policy cannot be found
// mockPolicyManager.GetPolicyReturns(nil, false)
// err = cs.VerifyBlockSignature([]*protoutil.SignedData{}, nil)
// require.EqualError(t, err, "policy /Channel/Orderer/BlockValidation wasn't found")

// mockPolicyManager.GetPolicyReturns(mockPolicy, true)
// // Scenario II: Policy manager finds policy, but it evaluates
// // to error.
// mockPolicy.EvaluateSignedDataReturns(errors.New("invalid signature"))
// err = cs.VerifyBlockSignature([]*protoutil.SignedData{}, nil)
// require.EqualError(t, err, "block verification failed: invalid signature")

// // Scenario III: Policy manager finds policy, and it evaluates to success
// mockPolicy.EvaluateSignedDataReturns(nil)
// require.NoError(t, cs.VerifyBlockSignature([]*protoutil.SignedData{}, nil))

// // Scenario IV: A bad config envelope is passed
// err = cs.VerifyBlockSignature([]*protoutil.SignedData{}, &common.ConfigEnvelope{})
// require.EqualError(t, err, "channelconfig Config cannot be nil")

// // Scenario V: A valid config envelope is passed
// require.NoError(t, cs.VerifyBlockSignature([]*protoutil.SignedData{}, testConfigEnvelope(t)))
// }

func testConfigEnvelope(t *testing.T) *common.ConfigEnvelope {
conf := genesisconfig.Load(genesisconfig.SampleInsecureSoloProfile, configtest.GetDevConfigDir())
group, err := encoder.NewChannelGroup(conf)
Expand Down
51 changes: 2 additions & 49 deletions orderer/common/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -820,12 +820,11 @@ func initializeMultichannelRegistrar(
if bootstrapBlock != nil && isClusterType(bootstrapBlock, bccsp) {
// with a system channel
consenterType := onboarding.ConsensusType(bootstrapBlock, bccsp)
fmt.Printf("consenterType: %s\n", consenterType)
switch consenterType {
case "etcdraft":
initializeEtcdraftConsenter(consenters, conf, lf, clusterDialer, bootstrapBlock, repInitiator, srvConf, srv, registrar, metricsProvider, bccsp)
case "BFT":
initializeSmartBFTConsenter(signer, dpmr, consenters, conf, lf, clusterDialer, bootstrapBlock, repInitiator, srvConf, srv, registrar, metricsProvider, bccsp)
logger.Panicf("Orderer and consensus config conflict. BFT consensus is supported only with channel participation API")
default:
logger.Panicf("Unknown cluster type consenter")
}
Expand All @@ -834,24 +833,20 @@ func initializeMultichannelRegistrar(
consenterType := "BFT"
bootstrapBlock := initSystemChannelWithJoinBlock(conf, bccsp, lf)
if bootstrapBlock != nil {
fmt.Println("DEBUG_bootstrapBlock is not nil")
consenterType = onboarding.ConsensusType(bootstrapBlock, bccsp)
} else {
fmt.Println("DEBUG_bootstrapBlock is nil")
// load consensus type from orderer config
var consensusConfig localconfig.Consensus
if err := mapstructure.Decode(conf.Consensus, &consensusConfig); err == nil && consensusConfig.Type != "" {
consenterType = consensusConfig.Type
}
}

fmt.Printf("DEBUG_consenterType:%v\n", consenterType)
// the orderer can start without channels at all and have an initialized cluster type consenter
switch consenterType {
case "etcdraft":
consenters["etcdraft"] = etcdraft.New(clusterDialer, conf, srvConf, srv, registrar, nil, metricsProvider, bccsp)
case "BFT":
consenters["BFT"] = smartbft.New(nil, dpmr.Registry(), signer, clusterDialer, conf, srvConf, srv, registrar, metricsProvider, bccsp)
consenters["BFT"] = smartbft.New(dpmr.Registry(), signer, clusterDialer, conf, srvConf, srv, registrar, metricsProvider, bccsp)
default:
logger.Panicf("Unknown cluster type consenter '%s'", consenterType)
}
Expand Down Expand Up @@ -889,48 +884,6 @@ func initializeEtcdraftConsenter(consenters map[string]consensus.Consenter, conf
consenters["etcdraft"] = raftConsenter
}

func initializeSmartBFTConsenter(
signer identity.SignerSerializer,
dpmr *DynamicPolicyManagerRegistry,
consenters map[string]consensus.Consenter,
conf *localconfig.TopLevel,
lf blockledger.Factory,
clusterDialer *cluster.PredicateDialer,
bootstrapBlock *cb.Block,
ri *onboarding.ReplicationInitiator,
srvConf comm.ServerConfig,
srv *comm.GRPCServer,
registrar *multichannel.Registrar,
metricsProvider metrics.Provider,
bccsp bccsp.BCCSP,
) *smartbft.Consenter {
fmt.Println("DEBUG-initializeSmartBFTConsenter called")
systemChannelName, err := protoutil.GetChannelIDFromBlock(bootstrapBlock)
if err != nil {
logger.Panicf("Failed extracting system channel name from bootstrap block: %v", err)
}
systemLedger, err := lf.GetOrCreate(systemChannelName)
if err != nil {
logger.Panicf("Failed obtaining system channel (%s) ledger: %v", systemChannelName, err)
}
getConfigBlock := func() *cb.Block {
return multichannel.ConfigBlockOrPanic(systemLedger)
}
icr := onboarding.NewInactiveChainReplicator(ri, getConfigBlock, ri.RegisterChain, conf.General.Cluster.ReplicationBackgroundRefreshInterval)

// Use the inactiveChainReplicator as a channel lister, since it has knowledge
// of all inactive chains.
// This is to prevent us pulling the entire system chain when attempting to enumerate
// the channels in the system.
ri.ChannelLister = icr

go icr.Run()
smartBFTConsenter := smartbft.New(icr, dpmr.Registry(), signer, clusterDialer, conf, srvConf, srv, registrar, metricsProvider, bccsp)
consenters["BFT"] = smartBFTConsenter

return smartBFTConsenter
}

func newOperationsSystem(ops localconfig.Operations, metrics localconfig.Metrics) *operations.System {
return operations.NewSystem(operations.Options{
Options: fabhttp.Options{
Expand Down
4 changes: 2 additions & 2 deletions orderer/consensus/smartbft/assembler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func TestAssembler(t *testing.T) {
{
name: "Must not contain an invalid request",
panicVal: "Programming error, received bad envelope but should have" +
" validated it: error unmarshalling Envelope: proto:\u00a0cannot parse invalid wire-format data",
" validated it: error unmarshalling Envelope: proto: cannot parse invalid wire-format data",
requests: [][]byte{{1, 2, 3}},
},
{
Expand Down Expand Up @@ -85,7 +85,7 @@ func TestAssembler(t *testing.T) {

if testCase.panicVal != "" {

require.PanicsWithValue(t, testCase.panicVal, func() {
require.Panics(t, func() {
assembler.AssembleProposal([]byte{1, 2, 3}, testCase.requests)
})
return
Expand Down
5 changes: 3 additions & 2 deletions orderer/consensus/smartbft/configverifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package smartbft

import (
"fmt"
"math"

mspa "github.com/hyperledger/fabric-protos-go/msp"
"github.com/hyperledger/fabric/common/policydsl"
Expand Down Expand Up @@ -98,7 +99,7 @@ func (cbv *ConfigBlockValidator) ValidateConfig(envelope *cb.Envelope) error {
}

func (cbv *ConfigBlockValidator) checkConsentersMatchPolicy(conf *cb.Config) error {
// TODO: check nil pointes everywhere
// TODO: check nil pointers everywhere

ords := &cb.Orderers{}
if err := proto.Unmarshal(conf.ChannelGroup.Groups["Orderer"].Values["Orderers"].Value, ords); err != nil {
Expand All @@ -123,7 +124,7 @@ func (cbv *ConfigBlockValidator) checkConsentersMatchPolicy(conf *cb.Config) err
}

sp := &cb.SignaturePolicyEnvelope{
Rule: policydsl.NOutOf(int32(2*f+1), pols),
Rule: policydsl.NOutOf(int32(math.Ceil(float64(n+f+1)/2)), pols),
Identities: identities,
}

Expand Down
Loading

0 comments on commit 25cdcfd

Please sign in to comment.