Skip to content

Commit

Permalink
[FAB-18237] always update stateInfo message upon chaincode update
Browse files Browse the repository at this point in the history
With the change of FAB-18208, gossip saves CPU cycles by only updating
metadata information if peer membership is not empty.

However, this makes discovery incapable of operating in case
anchor/bootstrap peers are not defined, or, in case
the peer is the only peer in the network.

This change makes gossip always update its information, including
signing the stateInfo message, whenever it receives a chaincode update.

Change-Id: Iaf04441944a3fe5d889233d35bdcb1173c31e2bc
Signed-off-by: yacovm <yacovm@il.ibm.com>
  • Loading branch information
yacovm authored and C0rWin committed Sep 23, 2020
1 parent f32cb81 commit 6b1ac6f
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 5 deletions.
14 changes: 13 additions & 1 deletion gossip/gossip/channel/channel.go
Expand Up @@ -414,14 +414,18 @@ func (gc *gossipChannel) publishStateInfo() {
return
}

gc.publishSignedStateInfoMessage()
atomic.StoreInt32(&gc.shouldGossipStateInfo, int32(0))
}

func (gc *gossipChannel) publishSignedStateInfoMessage() {
stateInfoMsg, err := gc.setupSignedStateInfoMessage()
if err != nil {
gc.logger.Errorf("Failed creating signed state info message: %v", err)
return
}
gc.stateInfoMsgStore.Add(stateInfoMsg)
gc.Gossip(stateInfoMsg)
atomic.StoreInt32(&gc.shouldGossipStateInfo, int32(0))
}

func (gc *gossipChannel) setupSignedStateInfoMessage() (*protoext.SignedGossipMessage, error) {
Expand Down Expand Up @@ -928,6 +932,14 @@ func (gc *gossipChannel) UpdateLedgerHeight(height uint64) {
// UpdateChaincodes updates the chaincodes the peer publishes
// to other peers in the channel
func (gc *gossipChannel) UpdateChaincodes(chaincodes []*proto.Chaincode) {
// Always publish the signed state info message regardless.
// We do this because we have to update our data structures
// with the new chaincodes installed/instantiated, to be able to
// respond to discovery requests, no matter if we see other peers
// in the membership, or do not see them.

defer gc.publishSignedStateInfoMessage()

gc.Lock()
defer gc.Unlock()

Expand Down
8 changes: 8 additions & 0 deletions gossip/gossip/channel/channel_test.go
Expand Up @@ -1132,6 +1132,14 @@ func TestNoGossipOrSigningWhenEmptyMembership(t *testing.T) {
time.Sleep(conf.PublishStateInfoInterval * 3)
// We haven't signed anything
assert.Equal(t, uint32(2), atomic.LoadUint32(&adapter.signCallCount))

assert.Empty(t, gc.Self().GetStateInfo().Properties.Chaincodes)
gossipedWG.Add(1)
// Now, update chaincodes and check our chaincode information was indeed updated
gc.UpdateChaincodes([]*proto.Chaincode{{Name: "mycc"}})
// We should have signed regardless!
assert.Equal(t, uint32(3), atomic.LoadUint32(&adapter.signCallCount))
assert.Equal(t, "mycc", gc.Self().GetStateInfo().Properties.Chaincodes[0].Name)
}

func TestChannelPulledBadBlocks(t *testing.T) {
Expand Down
43 changes: 39 additions & 4 deletions integration/discovery/discovery_test.go
Expand Up @@ -84,7 +84,6 @@ var _ = Describe("DiscoveryService", func() {

orderer = network.Orderer("orderer")
network.CreateAndJoinChannel(orderer, "testchannel")
network.UpdateChannelAnchors(orderer, "testchannel")

org1Peer0 = network.Peer("Org1", "peer0")
org2Peer0 = network.Peer("Org2", "peer0")
Expand All @@ -102,10 +101,46 @@ var _ = Describe("DiscoveryService", func() {
os.RemoveAll(testDir)
})

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 network configuration, endorsers, and peer membership", func() {
//
// discovering network configuration information
//
By("Updating anchor peers")
network.UpdateChannelAnchors(orderer, "testchannel")

By("retrieving the configuration")
config := commands.Config{
Expand Down

0 comments on commit 6b1ac6f

Please sign in to comment.