go_study/fabric-main/integration/discovery/discovery_test.go

897 lines
37 KiB
Go

/*
Copyright IBM Corp All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package discovery
import (
"encoding/json"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"syscall"
"time"
docker "github.com/fsouza/go-dockerclient"
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric-protos-go/common"
"github.com/hyperledger/fabric-protos-go/discovery"
pm "github.com/hyperledger/fabric-protos-go/msp"
"github.com/hyperledger/fabric/common/policydsl"
"github.com/hyperledger/fabric/integration/channelparticipation"
"github.com/hyperledger/fabric/integration/nwo"
"github.com/hyperledger/fabric/integration/nwo/commands"
"github.com/hyperledger/fabric/msp"
"github.com/hyperledger/fabric/protoutil"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
"github.com/onsi/gomega/gexec"
"github.com/tedsuo/ifrit"
ginkgomon "github.com/tedsuo/ifrit/ginkgomon_v2"
)
var _ = Describe("DiscoveryService", func() {
var (
testDir string
client *docker.Client
config *nwo.Config
network *nwo.Network
ordererRunner *ginkgomon.Runner
ordererProcess ifrit.Process
peerProcesses []ifrit.Process
orderer *nwo.Orderer
org1Peer0 *nwo.Peer
org2Peer0 *nwo.Peer
org3Peer0 *nwo.Peer
)
BeforeEach(func() {
var err error
testDir, err = ioutil.TempDir("", "e2e-sd")
Expect(err).NotTo(HaveOccurred())
client, err = docker.NewClientFromEnv()
Expect(err).NotTo(HaveOccurred())
config = nwo.BasicEtcdRaft()
Expect(config.Peers).To(HaveLen(2))
})
AfterEach(func() {
if ordererProcess != nil {
ordererProcess.Signal(syscall.SIGTERM)
Eventually(ordererProcess.Wait(), network.EventuallyTimeout).Should(Receive())
}
for _, process := range peerProcesses {
process.Signal(syscall.SIGTERM)
Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive())
}
if network != nil {
network.Cleanup()
}
os.RemoveAll(testDir)
})
Describe("basic etcdraft network without anchor peers", func() {
BeforeEach(func() {
By("generating a network with no anchor peers defined")
// disable all anchor peers
for _, p := range config.Peers {
for _, pc := range p.Channels {
pc.Anchor = false
}
}
network = nwo.New(config, testDir, client, StartPort(), components)
network.GenerateConfigTree()
network.Bootstrap()
By("asserting there are no anchor peers in the genesis block")
assertAnchorPeers(network, false, "testchannel", "Org1", "Org2")
// Start all the fabric processes
var peerProcess ifrit.Process
ordererRunner, ordererProcess, peerProcess = network.StartSingleOrdererNetwork("orderer")
peerProcesses = append(peerProcesses, peerProcess)
orderer = network.Orderer("orderer")
channelparticipation.JoinOrdererJoinPeersAppChannel(network, "testchannel", orderer, ordererRunner)
org1Peer0 = network.Peer("Org1", "peer0")
org2Peer0 = network.Peer("Org2", "peer0")
})
It("discovers network configuration even without anchor peers present", func() {
chaincodeWhenNoAnchorPeers := nwo.Chaincode{
Name: "noanchorpeersjustyet",
Version: "1.0",
Path: "github.com/hyperledger/fabric/integration/chaincode/simple/cmd",
Ctor: `{"Args":["init","a","100","b","200"]}`,
Policy: `OR ('Org1MSP.member')`,
}
By("Deploying chaincode before anchor peers are defined in the channel")
nwo.DeployChaincodeLegacy(network, "testchannel", orderer, chaincodeWhenNoAnchorPeers, org1Peer0)
endorsersForChaincodeBeforeAnchorPeersExist := commands.Endorsers{
UserCert: network.PeerUserCert(org1Peer0, "User1"),
UserKey: network.PeerUserKey(org1Peer0, "User1"),
MSPID: network.Organization(org1Peer0.Organization).MSPID,
Server: network.PeerAddress(org1Peer0, nwo.ListenPort),
Channel: "testchannel",
Chaincode: chaincodeWhenNoAnchorPeers.Name,
}
discoveryQuery := discoverEndorsers(network, endorsersForChaincodeBeforeAnchorPeersExist)
Eventually(discoveryQuery, network.EventuallyTimeout).Should(BeEquivalentTo(
[]ChaincodeEndorsers{
{
Chaincode: chaincodeWhenNoAnchorPeers.Name,
EndorsersByGroups: map[string][]nwo.DiscoveredPeer{
"G0": {network.DiscoveredPeer(org1Peer0)},
},
Layouts: []*discovery.Layout{
{
QuantitiesByGroup: map[string]uint32{"G0": 1},
},
},
},
},
))
})
It("discovers all peers after explicitly updating anchor peers", func() {
By("discovering peers without anchors yields partitioned information")
Eventually(nwo.DiscoverPeers(network, org1Peer0, "User1", "testchannel"), network.EventuallyTimeout).Should(ConsistOf(
network.DiscoveredPeer(org1Peer0, "_lifecycle"),
))
Eventually(nwo.DiscoverPeers(network, org2Peer0, "User1", "testchannel"), network.EventuallyTimeout).Should(ConsistOf(
network.DiscoveredPeer(org2Peer0, "_lifecycle"),
))
By("explicitly setting anchor peers on both organizations")
network.UpdateOrgAnchorPeers(orderer, "testchannel", "Org1", network.PeersInOrg("Org1"))
network.UpdateOrgAnchorPeers(orderer, "testchannel", "Org2", network.PeersInOrg("Org2"))
config := nwo.GetConfig(network, org1Peer0, orderer, "testchannel")
configGroups := config.GetChannelGroup().GetGroups()["Application"]
Expect(configGroups.GetGroups()["Org1"].GetValues()["AnchorPeers"].GetValue()).ToNot(BeEmpty())
Expect(configGroups.GetGroups()["Org2"].GetValues()["AnchorPeers"].GetValue()).ToNot(BeEmpty())
By("discovering peers with anchors yields complete information")
Eventually(nwo.DiscoverPeers(network, org1Peer0, "User1", "testchannel"), network.EventuallyTimeout).Should(ConsistOf(
network.DiscoveredPeer(org1Peer0, "_lifecycle"),
network.DiscoveredPeer(org2Peer0, "_lifecycle"),
))
Eventually(nwo.DiscoverPeers(network, org2Peer0, "User1", "testchannel"), network.EventuallyTimeout).Should(ConsistOf(
network.DiscoveredPeer(org1Peer0, "_lifecycle"),
network.DiscoveredPeer(org2Peer0, "_lifecycle"),
))
})
})
Describe("basic etcdraft network with anchor peers", func() {
BeforeEach(func() {
By("generating a network with anchor peers defined and adding a 3rd org")
// add org3 with one peer (to generate cryptogen and configtx files)
config.Organizations = append(config.Organizations, &nwo.Organization{
Name: "Org3",
MSPID: "Org3MSP",
Domain: "org3.example.com",
EnableNodeOUs: true,
Users: 2,
CA: &nwo.CA{Hostname: "ca"},
})
config.Profiles[0].Organizations = append(config.Profiles[0].Organizations, "Org3")
config.Peers = append(config.Peers,
&nwo.Peer{
Name: "peer0",
Organization: "Org3",
Channels: []*nwo.PeerChannel{
{Name: "testchannel", Anchor: true},
},
},
)
network = nwo.New(config, testDir, client, StartPort(), components)
network.GenerateConfigTree()
network.Bootstrap()
// initially remove Org3 peer0 from the network and later add it back to test joinbysnapshot
peers := []*nwo.Peer{}
for _, p := range network.Peers {
if p.Organization != "Org3" {
peers = append(peers, p)
}
}
network.Peers = peers
By("asserting the genesis block has anchor peers defined")
assertAnchorPeers(network, true, "testchannel", "Org1", "Org2", "Org3")
// Start all the fabric processes
var peerProcess ifrit.Process
ordererRunner, ordererProcess, peerProcess = network.StartSingleOrdererNetwork("orderer")
peerProcesses = append(peerProcesses, peerProcess)
orderer = network.Orderer("orderer")
channelparticipation.JoinOrdererJoinPeersAppChannel(network, "testchannel", orderer, ordererRunner)
org1Peer0 = network.Peer("Org1", "peer0")
org2Peer0 = network.Peer("Org2", "peer0")
})
It("discovers network configuration, endorsers, and peer membership", func() {
//
// bootstrapping a peer from snapshot
//
By("generating a snapshot at current block number on org1Peer0")
blockNum := nwo.GetLedgerHeight(network, org1Peer0, "testchannel") - 1
submitSnapshotRequest(network, "testchannel", 0, org1Peer0, "Snapshot request submitted successfully")
By("verifying snapshot completed on org1Peer0")
verifyNoPendingSnapshotRequest(network, org1Peer0, "testchannel")
snapshotDir := filepath.Join(network.PeerDir(org1Peer0), "filesystem", "snapshots", "completed", "testchannel", strconv.Itoa(blockNum))
By("adding peer org3Peer0 to the network")
org3Peer0 = &nwo.Peer{
Name: "peer0",
Organization: "Org3",
Channels: []*nwo.PeerChannel{
{Name: "testchannel", Anchor: true},
},
}
network.Peers = append(network.Peers, org3Peer0)
By("starting peer org3Peer0")
peerRunner := network.PeerRunner(org3Peer0)
process := ifrit.Invoke(peerRunner)
Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed())
peerProcesses = append(peerProcesses, process)
By("joining peer org3Peer0 to channel by a snapshot")
joinBySnapshot(network, orderer, org3Peer0, "testchannel", snapshotDir)
//
// retrieving configuration and validating membership
//
By("retrieving the configuration from org1Peer0")
discoveredConfig := discoverConfiguration(network, org1Peer0)
By("retrieving the configuration from org3Peer0")
discoveredConfig2 := discoverConfiguration(network, org3Peer0)
By("comparing configuration from org1Peer0 and org3Peer0")
Expect(proto.Equal(discoveredConfig, discoveredConfig2)).To(BeTrue())
By("validating the membership data")
Expect(discoveredConfig.Msps).To(HaveLen(len(network.Organizations)))
for _, o := range network.Orderers {
org := network.Organization(o.Organization)
mspConfig, err := msp.GetVerifyingMspConfig(network.OrdererOrgMSPDir(org), org.MSPID, "bccsp")
Expect(err).NotTo(HaveOccurred())
Expect(discoveredConfig.Msps[org.MSPID]).To(Equal(unmarshalFabricMSPConfig(mspConfig)))
}
for _, p := range network.Peers {
org := network.Organization(p.Organization)
mspConfig, err := msp.GetVerifyingMspConfig(network.PeerOrgMSPDir(org), org.MSPID, "bccsp")
Expect(err).NotTo(HaveOccurred())
Expect(discoveredConfig.Msps[org.MSPID]).To(Equal(unmarshalFabricMSPConfig(mspConfig)))
}
By("validating the orderers")
Expect(discoveredConfig.Orderers).To(HaveLen(len(network.Orderers)))
for _, orderer := range network.Orderers {
ordererMSPID := network.Organization(orderer.Organization).MSPID
Expect(discoveredConfig.Orderers[ordererMSPID].Endpoint).To(ConsistOf(
&discovery.Endpoint{Host: "127.0.0.1", Port: uint32(network.OrdererPort(orderer, nwo.ListenPort))},
))
}
//
// discovering peers and endorsers
//
By("discovering peers before deploying any user chaincodes")
Eventually(nwo.DiscoverPeers(network, org1Peer0, "User1", "testchannel"), network.EventuallyTimeout).Should(ConsistOf(
network.DiscoveredPeer(org1Peer0, "_lifecycle"),
network.DiscoveredPeer(org2Peer0, "_lifecycle"),
network.DiscoveredPeer(org3Peer0, "_lifecycle"),
))
By("discovering endorsers when missing chaincode")
endorsers := commands.Endorsers{
UserCert: network.PeerUserCert(org1Peer0, "User1"),
UserKey: network.PeerUserKey(org1Peer0, "User1"),
MSPID: network.Organization(org1Peer0.Organization).MSPID,
Server: network.PeerAddress(org1Peer0, nwo.ListenPort),
Channel: "testchannel",
Chaincode: "mycc",
}
sess, err := network.Discover(endorsers)
Expect(err).NotTo(HaveOccurred())
Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
Expect(sess.Err).To(gbytes.Say(`failed constructing descriptor for chaincodes:<name:"mycc"`))
By("installing and instantiating chaincode on org1.peer0")
chaincode := nwo.Chaincode{
Name: "mycc",
Version: "1.0",
Path: "github.com/hyperledger/fabric/integration/chaincode/simple/cmd",
Ctor: `{"Args":["init","a","100","b","200"]}`,
Policy: `OR (AND ('Org1MSP.member','Org2MSP.member'), AND ('Org1MSP.member','Org3MSP.member'), AND ('Org2MSP.member','Org3MSP.member'))`,
}
nwo.DeployChaincodeLegacy(network, "testchannel", orderer, chaincode, org1Peer0)
By("discovering peers after installing and instantiating chaincode using org1's peer")
dp := nwo.DiscoverPeers(network, org1Peer0, "User1", "testchannel")
Eventually(peersWithChaincode(dp, "mycc"), network.EventuallyTimeout).Should(HaveLen(1))
peersWithCC := peersWithChaincode(dp, "mycc")()
Expect(peersWithCC).To(ConsistOf(network.DiscoveredPeer(org1Peer0, "_lifecycle", "mycc")))
By("discovering endorsers for chaincode that has not been installed to enough orgs to satisfy endorsement policy")
sess, err = network.Discover(endorsers)
Expect(err).NotTo(HaveOccurred())
Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
Expect(sess.Err).To(gbytes.Say(`failed constructing descriptor for chaincodes:<name:"mycc"`))
By("installing chaincode to enough organizations to satisfy the endorsement policy")
nwo.InstallChaincodeLegacy(network, chaincode, org2Peer0)
By("discovering peers after installing chaincode to org2's peer")
dp = nwo.DiscoverPeers(network, org1Peer0, "User1", "testchannel")
Eventually(peersWithChaincode(dp, "mycc"), network.EventuallyTimeout).Should(HaveLen(2))
peersWithCC = peersWithChaincode(dp, "mycc")()
Expect(peersWithCC).To(ConsistOf(
network.DiscoveredPeer(org1Peer0, "_lifecycle", "mycc"),
network.DiscoveredPeer(org2Peer0, "_lifecycle", "mycc"),
))
By("discovering endorsers for chaincode that has been installed to org1 and org2")
de := discoverEndorsers(network, endorsers)
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
))
discovered := de()
Expect(discovered).To(HaveLen(1))
Expect(discovered[0].Layouts).To(HaveLen(1))
Expect(discovered[0].Layouts[0].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
By("installing chaincode to all orgs")
nwo.InstallChaincodeLegacy(network, chaincode, org3Peer0)
By("discovering peers after installing and instantiating chaincode all org peers")
dp = nwo.DiscoverPeers(network, org1Peer0, "User1", "testchannel")
Eventually(peersWithChaincode(dp, "mycc"), network.EventuallyTimeout).Should(HaveLen(3))
peersWithCC = peersWithChaincode(dp, "mycc")()
Expect(peersWithCC).To(ConsistOf(
network.DiscoveredPeer(org1Peer0, "_lifecycle", "mycc"),
network.DiscoveredPeer(org2Peer0, "_lifecycle", "mycc"),
network.DiscoveredPeer(org3Peer0, "_lifecycle", "mycc"),
))
By("discovering endorsers for chaincode that has been installed to all orgs")
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org3Peer0)},
))
discovered = de()
Expect(discovered).To(HaveLen(1))
Expect(discovered[0].Layouts).To(HaveLen(3))
Expect(discovered[0].Layouts[0].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
Expect(discovered[0].Layouts[1].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
Expect(discovered[0].Layouts[2].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
By("upgrading chaincode and adding a collections config")
chaincode.Name = "mycc"
chaincode.Version = "2.0"
chaincode.CollectionsConfig = filepath.Join("testdata", "collections_config_org1_org2.json")
nwo.UpgradeChaincodeLegacy(network, "testchannel", orderer, chaincode, org1Peer0, org2Peer0, org3Peer0)
By("discovering endorsers for chaincode with a private collection")
endorsers.Collection = "mycc:collectionMarbles"
de = discoverEndorsers(network, endorsers)
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
))
discovered = de()
Expect(discovered).To(HaveLen(1))
Expect(discovered[0].Layouts).To(HaveLen(1))
Expect(discovered[0].Layouts[0].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
endorsers.Collection = "mycc:collectionMarbles"
endorsers.NoPrivateReads = []string{"mycc"}
de = discoverEndorsers(network, endorsers)
By("discovering endorsers for a blind write with a collection consists of all possible peers")
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org3Peer0)},
))
By("changing the channel policy")
currentConfig := nwo.GetConfig(network, org3Peer0, orderer, "testchannel")
updatedConfig := proto.Clone(currentConfig).(*common.Config)
updatedConfig.ChannelGroup.Groups["Application"].Groups["Org3"].Policies["Writers"].Policy.Value = protoutil.MarshalOrPanic(policydsl.SignedByMspAdmin("Org3MSP"))
nwo.UpdateConfig(network, orderer, "testchannel", currentConfig, updatedConfig, true, org3Peer0)
By("trying to discover endorsers as an org3 admin")
endorsers = commands.Endorsers{
UserCert: network.PeerUserCert(org3Peer0, "Admin"),
UserKey: network.PeerUserKey(org3Peer0, "Admin"),
MSPID: network.Organization(org3Peer0.Organization).MSPID,
Server: network.PeerAddress(org3Peer0, nwo.ListenPort),
Channel: "testchannel",
Chaincode: "mycc",
}
de = discoverEndorsers(network, endorsers)
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
ConsistOf(network.DiscoveredPeer(org1Peer0)),
ConsistOf(network.DiscoveredPeer(org2Peer0)),
ConsistOf(network.DiscoveredPeer(org3Peer0)),
))
By("trying to discover endorsers as an org3 member")
endorsers = commands.Endorsers{
UserCert: network.PeerUserCert(org3Peer0, "User1"),
UserKey: network.PeerUserKey(org3Peer0, "User1"),
MSPID: network.Organization(org3Peer0.Organization).MSPID,
Server: network.PeerAddress(org3Peer0, nwo.ListenPort),
Channel: "testchannel",
Chaincode: "mycc",
}
sess, err = network.Discover(endorsers)
Expect(err).NotTo(HaveOccurred())
Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
Expect(sess.Err).To(gbytes.Say(`access denied`))
By("discovering endorsers for _lifecycle system chaincode before enabling V2_0 capabilities")
endorsers = commands.Endorsers{
UserCert: network.PeerUserCert(org1Peer0, "User1"),
UserKey: network.PeerUserKey(org1Peer0, "User1"),
MSPID: network.Organization(org1Peer0.Organization).MSPID,
Server: network.PeerAddress(org1Peer0, nwo.ListenPort),
Channel: "testchannel",
Chaincode: "_lifecycle",
}
sess, err = network.Discover(endorsers)
Expect(err).NotTo(HaveOccurred())
Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
Expect(sess.Err).To(gbytes.Say(`failed constructing descriptor for chaincodes:<name:"_lifecycle"`))
//
// using _lifecycle
//
By("enabling V2_0 application capabilities on the channel")
nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, org1Peer0, org2Peer0, org3Peer0)
By("ensuring peers are still discoverable after enabling V2_0 application capabilities")
dp = nwo.DiscoverPeers(network, org1Peer0, "User1", "testchannel")
Eventually(peersWithChaincode(dp, "mycc"), network.EventuallyTimeout).Should(HaveLen(3))
peersWithCC = peersWithChaincode(dp, "mycc")()
Expect(peersWithCC).To(ConsistOf(
network.DiscoveredPeer(org1Peer0, "_lifecycle", "mycc"),
network.DiscoveredPeer(org2Peer0, "_lifecycle", "mycc"),
network.DiscoveredPeer(org3Peer0, "_lifecycle", "mycc"),
))
By("ensuring endorsers for mycc are still discoverable after upgrading to V2_0 application capabilities")
endorsers = commands.Endorsers{
UserCert: network.PeerUserCert(org1Peer0, "User1"),
UserKey: network.PeerUserKey(org1Peer0, "User1"),
MSPID: network.Organization(org1Peer0.Organization).MSPID,
Server: network.PeerAddress(org1Peer0, nwo.ListenPort),
Channel: "testchannel",
Chaincode: "mycc",
}
de = discoverEndorsers(network, endorsers)
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org3Peer0)},
))
By("ensuring endorsers for mycc's collection are still discoverable after upgrading to V2_0 application capabilities")
endorsers.Collection = "mycc:collectionMarbles"
de = discoverEndorsers(network, endorsers)
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
))
By("discovering endorsers for _lifecycle system chaincode")
endorsers = commands.Endorsers{
UserCert: network.PeerUserCert(org1Peer0, "User1"),
UserKey: network.PeerUserKey(org1Peer0, "User1"),
MSPID: network.Organization(org1Peer0.Organization).MSPID,
Server: network.PeerAddress(org1Peer0, nwo.ListenPort),
Channel: "testchannel",
Chaincode: "_lifecycle",
}
de = discoverEndorsers(network, endorsers)
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org3Peer0)},
))
discovered = de()
Expect(discovered).To(HaveLen(1))
Expect(discovered[0].Layouts).To(HaveLen(3))
Expect(discovered[0].Layouts[0].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
Expect(discovered[0].Layouts[1].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
Expect(discovered[0].Layouts[2].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
By("discovering endorsers when missing chaincode")
endorsers = commands.Endorsers{
UserCert: network.PeerUserCert(org1Peer0, "User1"),
UserKey: network.PeerUserKey(org1Peer0, "User1"),
MSPID: network.Organization(org1Peer0.Organization).MSPID,
Server: network.PeerAddress(org1Peer0, nwo.ListenPort),
Channel: "testchannel",
Chaincode: "mycc-lifecycle",
}
sess, err = network.Discover(endorsers)
Expect(err).NotTo(HaveOccurred())
Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
Expect(sess.Err).To(gbytes.Say(`failed constructing descriptor for chaincodes:<name:"mycc-lifecycle"`))
By("deploying chaincode using org1 and org2")
chaincodePath := components.Build("github.com/hyperledger/fabric/integration/chaincode/simple/cmd")
chaincode = nwo.Chaincode{
Name: "mycc-lifecycle",
Version: "1.0",
Lang: "binary",
PackageFile: filepath.Join(testDir, "simplecc.tar.gz"),
Path: chaincodePath,
Ctor: `{"Args":["init","a","100","b","200"]}`,
ChannelConfigPolicy: "/Channel/Application/Endorsement",
Sequence: "1",
InitRequired: true,
Label: "my_prebuilt_chaincode",
}
By("packaging chaincode")
nwo.PackageChaincodeBinary(chaincode)
By("installing chaincode to org1.peer0 and org2.peer0")
nwo.InstallChaincode(network, chaincode, org1Peer0, org2Peer0)
By("approving chaincode definition for org1 and org2")
for _, org := range []string{"Org1", "Org2"} {
nwo.ApproveChaincodeForMyOrg(network, "testchannel", orderer, chaincode, network.PeersInOrg(org)...)
}
By("committing chaincode definition using org1.peer0 and org2.peer0")
nwo.CommitChaincode(network, "testchannel", orderer, chaincode, org1Peer0, org1Peer0, org2Peer0)
nwo.InitChaincode(network, "testchannel", orderer, chaincode, org1Peer0, org2Peer0)
By("discovering endorsers for chaincode that has been installed to some orgs")
de = discoverEndorsers(network, endorsers)
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
))
discovered = de()
Expect(discovered).To(HaveLen(1))
Expect(discovered[0].Layouts).To(HaveLen(1))
Expect(discovered[0].Layouts[0].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
By("installing chaincode to all orgs")
nwo.InstallChaincode(network, chaincode, org3Peer0)
By("discovering endorsers for chaincode that has been installed to all orgs but not yet approved by org3")
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
))
By("ensuring peers are only discoverable that have the chaincode installed and approved")
dp = nwo.DiscoverPeers(network, org1Peer0, "User1", "testchannel")
Eventually(peersWithChaincode(dp, "mycc-lifecycle"), network.EventuallyTimeout).Should(HaveLen(2))
peersWithCC = peersWithChaincode(dp, "mycc-lifecycle")()
Expect(peersWithCC).To(ConsistOf(
network.DiscoveredPeer(org1Peer0, "mycc-lifecycle", "_lifecycle", "mycc"),
network.DiscoveredPeer(org2Peer0, "mycc-lifecycle", "_lifecycle", "mycc"),
))
By("approving chaincode definition for org3")
nwo.ApproveChaincodeForMyOrg(network, "testchannel", orderer, chaincode, network.PeersInOrg("Org3")...)
By("discovering endorsers for chaincode that has been installed and approved by all orgs")
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org3Peer0)},
))
By("discovering peers for chaincode that has been installed and approved by all orgs")
dp = nwo.DiscoverPeers(network, org1Peer0, "User1", "testchannel")
Eventually(peersWithChaincode(dp, "mycc-lifecycle"), network.EventuallyTimeout).Should(HaveLen(3))
peersWithCC = peersWithChaincode(dp, "mycc-lifecycle")()
Expect(peersWithCC).To(ConsistOf(
network.DiscoveredPeer(org1Peer0, "mycc-lifecycle", "_lifecycle", "mycc"),
network.DiscoveredPeer(org2Peer0, "mycc-lifecycle", "_lifecycle", "mycc"),
network.DiscoveredPeer(org3Peer0, "mycc-lifecycle", "_lifecycle", "mycc"),
))
By("updating the chaincode definition to sequence 2 to add a collections config")
chaincode.Sequence = "2"
chaincode.CollectionsConfig = filepath.Join("testdata", "collections_config_org1_org2.json")
for _, org := range []string{"Org1", "Org2"} {
nwo.ApproveChaincodeForMyOrg(network, "testchannel", orderer, chaincode, network.PeersInOrg(org)...)
}
By("committing the new chaincode definition using org1 and org2")
nwo.CheckCommitReadinessUntilReady(network, "testchannel", chaincode, []*nwo.Organization{network.Organization("Org1"), network.Organization("Org2")}, org1Peer0, org2Peer0, org3Peer0)
nwo.CommitChaincode(network, "testchannel", orderer, chaincode, org1Peer0, org1Peer0, org2Peer0)
By("discovering endorsers for sequence 2 that has only been approved by org1 and org2")
de = discoverEndorsers(network, endorsers)
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
))
By("approving the chaincode definition at sequence 2 by org3")
maxLedgerHeight := nwo.GetMaxLedgerHeight(network, "testchannel", org1Peer0, org2Peer0, org3Peer0)
nwo.ApproveChaincodeForMyOrg(network, "testchannel", orderer, chaincode, network.PeersInOrg("Org3")...)
nwo.WaitUntilEqualLedgerHeight(network, "testchannel", maxLedgerHeight+1, org1Peer0, org2Peer0, org3Peer0)
By("discovering endorsers for sequence 2 that has been approved by all orgs")
de = discoverEndorsers(network, endorsers)
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org3Peer0)},
))
By("discovering endorsers for chaincode with a private collection")
endorsers.Collection = "mycc-lifecycle:collectionMarbles"
de = discoverEndorsers(network, endorsers)
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
))
discovered = de()
Expect(discovered).To(HaveLen(1))
Expect(discovered[0].Layouts).To(HaveLen(1))
Expect(discovered[0].Layouts[0].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
By("upgrading a legacy chaincode for all peers")
nwo.DeployChaincode(network, "testchannel", orderer, nwo.Chaincode{
Name: "mycc",
Version: "2.0",
Lang: "binary",
PackageFile: filepath.Join(testDir, "simplecc.tar.gz"),
Path: chaincodePath,
SignaturePolicy: `AND ('Org1MSP.member', 'Org2MSP.member', 'Org3MSP.member')`,
Sequence: "1",
CollectionsConfig: filepath.Join("testdata", "collections_config_org1_org2_org3.json"),
Label: "my_prebuilt_chaincode",
})
By("discovering endorsers for chaincode that has been installed to all peers")
endorsers.Chaincode = "mycc"
endorsers.Collection = ""
de = discoverEndorsers(network, endorsers)
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
ConsistOf(network.DiscoveredPeer(org1Peer0)),
ConsistOf(network.DiscoveredPeer(org2Peer0)),
ConsistOf(network.DiscoveredPeer(org3Peer0)),
))
discovered = de()
Expect(discovered).To(HaveLen(1))
Expect(discovered[0].Layouts).To(HaveLen(1))
Expect(discovered[0].Layouts[0].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1), uint32(1)))
By("discovering endorsers for a collection without collection EP, using chaincode EP")
endorsers.Collection = "mycc:collectionMarbles"
de = discoverEndorsers(network, endorsers)
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
ConsistOf(network.DiscoveredPeer(org1Peer0)),
ConsistOf(network.DiscoveredPeer(org2Peer0)),
ConsistOf(network.DiscoveredPeer(org3Peer0)),
))
By("discovering endorsers for a collection with collection EP, using collection EP")
endorsers.Collection = "mycc:collectionDetails"
de = discoverEndorsers(network, endorsers)
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
ConsistOf(network.DiscoveredPeer(org1Peer0)),
ConsistOf(network.DiscoveredPeer(org2Peer0)),
))
discovered = de()
Expect(discovered).To(HaveLen(1))
Expect(discovered[0].Layouts).To(HaveLen(1))
Expect(discovered[0].Layouts[0].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
By("discovering endorsers for Org1 implicit collection")
endorsers.Collection = "mycc:_implicit_org_Org1MSP"
de = discoverEndorsers(network, endorsers)
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
ConsistOf(network.DiscoveredPeer(org1Peer0)),
))
discovered = de()
Expect(discovered).To(HaveLen(1))
Expect(discovered[0].Layouts).To(HaveLen(1))
Expect(discovered[0].Layouts[0].QuantitiesByGroup).To(ConsistOf(uint32(1)))
By("trying to discover endorsers as an org3 admin")
endorsers = commands.Endorsers{
UserCert: network.PeerUserCert(org3Peer0, "Admin"),
UserKey: network.PeerUserKey(org3Peer0, "Admin"),
MSPID: network.Organization(org3Peer0.Organization).MSPID,
Server: network.PeerAddress(org3Peer0, nwo.ListenPort),
Channel: "testchannel",
Chaincode: "mycc",
}
de = discoverEndorsers(network, endorsers)
Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
ConsistOf(network.DiscoveredPeer(org1Peer0)),
ConsistOf(network.DiscoveredPeer(org2Peer0)),
ConsistOf(network.DiscoveredPeer(org3Peer0)),
))
By("trying to discover endorsers as an org3 member")
endorsers = commands.Endorsers{
UserCert: network.PeerUserCert(org3Peer0, "User1"),
UserKey: network.PeerUserKey(org3Peer0, "User1"),
MSPID: network.Organization(org3Peer0.Organization).MSPID,
Server: network.PeerAddress(org3Peer0, nwo.ListenPort),
Channel: "testchannel",
Chaincode: "mycc-lifecycle",
}
sess, err = network.Discover(endorsers)
Expect(err).NotTo(HaveOccurred())
Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
Expect(sess.Err).To(gbytes.Say(`access denied`))
})
})
})
func assertAnchorPeers(network *nwo.Network, exist bool, channelID string, orgs ...string) {
// get the genesis block
configBlock := nwo.UnmarshalBlockFromFile(network.OutputBlockPath(channelID))
envelope, err := protoutil.GetEnvelopeFromBlock(configBlock.Data.Data[0])
Expect(err).NotTo(HaveOccurred())
// unmarshal the payload bytes
payload, err := protoutil.UnmarshalPayload(envelope.Payload)
Expect(err).NotTo(HaveOccurred())
// unmarshal the config envelope bytes
configEnv := &common.ConfigEnvelope{}
err = proto.Unmarshal(payload.Data, configEnv)
Expect(err).NotTo(HaveOccurred())
config := configEnv.GetConfig()
configGroups := config.GetChannelGroup().GetGroups()["Application"]
for _, org := range orgs {
if exist {
Expect(configGroups.GetGroups()[org].GetValues()["AnchorPeers"].GetValue()).ToNot(BeEmpty())
} else {
Expect(configGroups.GetGroups()[org].GetValues()["AnchorPeers"].GetValue()).To(BeEmpty())
}
}
}
type ChaincodeEndorsers struct {
Chaincode string
EndorsersByGroups map[string][]nwo.DiscoveredPeer
Layouts []*discovery.Layout
}
func discoverEndorsers(n *nwo.Network, command commands.Endorsers) func() []ChaincodeEndorsers {
return func() []ChaincodeEndorsers {
sess, err := n.Discover(command)
Expect(err).NotTo(HaveOccurred())
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit())
if sess.ExitCode() != 0 {
return nil
}
discovered := []ChaincodeEndorsers{}
err = json.Unmarshal(sess.Out.Contents(), &discovered)
Expect(err).NotTo(HaveOccurred())
return discovered
}
}
func endorsersByGroups(discover func() []ChaincodeEndorsers) func() map[string][]nwo.DiscoveredPeer {
return func() map[string][]nwo.DiscoveredPeer {
discovered := discover()
if len(discovered) == 1 {
return discovered[0].EndorsersByGroups
}
return map[string][]nwo.DiscoveredPeer{}
}
}
func peersWithChaincode(discover func() []nwo.DiscoveredPeer, ccName string) func() []nwo.DiscoveredPeer {
return func() []nwo.DiscoveredPeer {
peers := []nwo.DiscoveredPeer{}
for _, p := range discover() {
for _, cc := range p.Chaincodes {
if cc == ccName {
peers = append(peers, p)
}
}
}
return peers
}
}
func unmarshalFabricMSPConfig(c *pm.MSPConfig) *pm.FabricMSPConfig {
fabricConfig := &pm.FabricMSPConfig{}
err := proto.Unmarshal(c.Config, fabricConfig)
Expect(err).NotTo(HaveOccurred())
return fabricConfig
}
func discoverConfiguration(n *nwo.Network, peer *nwo.Peer) *discovery.ConfigResult {
config := commands.Config{
UserCert: n.PeerUserCert(peer, "User1"),
UserKey: n.PeerUserKey(peer, "User1"),
MSPID: n.Organization(peer.Organization).MSPID,
Server: n.PeerAddress(peer, nwo.ListenPort),
Channel: "testchannel",
}
sess, err := n.Discover(config)
Expect(err).NotTo(HaveOccurred())
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
By("unmarshalling the response")
discoveredConfig := &discovery.ConfigResult{}
err = json.Unmarshal(sess.Out.Contents(), &discoveredConfig)
Expect(err).NotTo(HaveOccurred())
return discoveredConfig
}
func submitSnapshotRequest(n *nwo.Network, channel string, blockNum int, peer *nwo.Peer, expectedMsg string) {
sess, err := n.PeerAdminSession(peer, commands.SnapshotSubmitRequest{
ChannelID: channel,
BlockNumber: strconv.Itoa(blockNum),
ClientAuth: n.ClientAuthRequired,
PeerAddress: n.PeerAddress(peer, nwo.ListenPort),
})
Expect(err).NotTo(HaveOccurred())
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
Expect(sess).To(gbytes.Say(expectedMsg))
}
func verifyNoPendingSnapshotRequest(n *nwo.Network, peer *nwo.Peer, channelID string) {
cmd := commands.SnapshotListPending{
ChannelID: channelID,
ClientAuth: n.ClientAuthRequired,
PeerAddress: n.PeerAddress(peer, nwo.ListenPort),
}
checkPending := func() string {
sess, err := n.PeerAdminSession(peer, cmd)
Expect(err).NotTo(HaveOccurred())
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
return string(sess.Buffer().Contents())
}
Eventually(checkPending, n.EventuallyTimeout, 10*time.Second).Should(ContainSubstring("Successfully got pending snapshot requests: []\n"))
}
func joinBySnapshot(n *nwo.Network, orderer *nwo.Orderer, peer *nwo.Peer, channelID string, snapshotDir string) {
n.JoinChannelBySnapshot(snapshotDir, peer)
By("calling JoinBySnapshotStatus until joinbysnapshot is completed")
checkStatus := func() string { return n.JoinBySnapshotStatus(peer) }
Eventually(checkStatus, n.EventuallyTimeout, 10*time.Second).Should(ContainSubstring("No joinbysnapshot operation is in progress"))
By("waiting for the peer to have the same ledger height")
channelHeight := nwo.GetMaxLedgerHeight(n, channelID, n.PeersWithChannel(channelID)...)
nwo.WaitUntilEqualLedgerHeight(n, channelID, channelHeight, peer)
}