github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/integration/e2e/instantiation_policy_test.go (about)

     1  /*
     2  Copyright hechain All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package e2e
     8  
     9  import (
    10  	"crypto/sha256"
    11  	"encoding/hex"
    12  	"io/ioutil"
    13  	"os"
    14  	"syscall"
    15  	"time"
    16  
    17  	docker "github.com/fsouza/go-dockerclient"
    18  	"github.com/golang/protobuf/proto"
    19  	"github.com/golang/protobuf/ptypes"
    20  	"github.com/hechain20/hechain/common/policydsl"
    21  	"github.com/hechain20/hechain/integration/nwo"
    22  	"github.com/hechain20/hechain/integration/nwo/commands"
    23  	"github.com/hechain20/hechain/integration/ordererclient"
    24  	"github.com/hyperledger/fabric-protos-go/common"
    25  	"github.com/hyperledger/fabric-protos-go/ledger/rwset"
    26  	"github.com/hyperledger/fabric-protos-go/ledger/rwset/kvrwset"
    27  	"github.com/hyperledger/fabric-protos-go/peer"
    28  
    29  	. "github.com/onsi/ginkgo"
    30  	. "github.com/onsi/gomega"
    31  	"github.com/onsi/gomega/gbytes"
    32  	"github.com/onsi/gomega/gexec"
    33  	"github.com/tedsuo/ifrit"
    34  )
    35  
    36  var _ = Describe("InstantiationPolicy", func() {
    37  	var (
    38  		testDir string
    39  		client  *docker.Client
    40  		network *nwo.Network
    41  		process ifrit.Process
    42  	)
    43  
    44  	BeforeEach(func() {
    45  		var err error
    46  		testDir, err = ioutil.TempDir("", "e2e")
    47  		Expect(err).NotTo(HaveOccurred())
    48  
    49  		client, err = docker.NewClientFromEnv()
    50  		Expect(err).NotTo(HaveOccurred())
    51  	})
    52  
    53  	AfterEach(func() {
    54  		if process != nil {
    55  			process.Signal(syscall.SIGTERM)
    56  			Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive())
    57  		}
    58  		if network != nil {
    59  			network.Cleanup()
    60  		}
    61  		os.RemoveAll(testDir)
    62  	})
    63  
    64  	Describe("single node etcdraft network with single peer", func() {
    65  		BeforeEach(func() {
    66  			config := nwo.MinimalRaft()
    67  			config.Profiles[1].Organizations = []string{"Org1", "Org2"}
    68  			network = nwo.New(config, testDir, client, StartPort(), components)
    69  			network.GenerateConfigTree()
    70  			network.Bootstrap()
    71  
    72  			networkRunner := network.NetworkGroupRunner()
    73  			process = ifrit.Invoke(networkRunner)
    74  			Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed())
    75  		})
    76  
    77  		It("honors the instantiation policy", func() {
    78  			orderer := network.Orderer("orderer")
    79  
    80  			org1Peer := network.Peer("Org1", "peer0")
    81  			org2Peer := network.Peer("Org2", "peer0")
    82  
    83  			network.CreateAndJoinChannel(orderer, "testchannel")
    84  
    85  			By("attempting to deploy with an unsatisfied instantiation policy")
    86  
    87  			goodDeploy := LSCCOperation{
    88  				Operation: "deploy",
    89  				ChannelID: "testchannel",
    90  				Name:      "fakecc",
    91  				Version:   "badip",
    92  				InstantiationOrgs: []*nwo.Organization{
    93  					network.Organization("Org2"),
    94  				},
    95  			}
    96  
    97  			ordererclient.Broadcast(network, orderer, goodDeploy.Tx(network.PeerUserSigner(org1Peer, "Admin")))
    98  
    99  			nwo.WaitUntilEqualLedgerHeight(network, "testchannel", 2, org1Peer)
   100  
   101  			Expect(ListInstantiatedLegacy(network, org1Peer, "testchannel")).NotTo(gbytes.Say("Name: fakecc, Version: badip"))
   102  
   103  			By("attempting to deploy with a satisfied instantiation policy")
   104  
   105  			badDeploy := LSCCOperation{
   106  				Operation: "deploy",
   107  				ChannelID: "testchannel",
   108  				Name:      "fakecc",
   109  				Version:   "goodip",
   110  				InstantiationOrgs: []*nwo.Organization{
   111  					network.Organization("Org1"),
   112  				},
   113  			}
   114  
   115  			ordererclient.Broadcast(network, orderer, badDeploy.Tx(network.PeerUserSigner(org1Peer, "Admin")))
   116  
   117  			nwo.WaitUntilEqualLedgerHeight(network, "testchannel", 3, org1Peer)
   118  			Expect(ListInstantiatedLegacy(network, org1Peer, "testchannel")).To(gbytes.Say("Name: fakecc, Version: goodip"))
   119  
   120  			By("upgrading without satisfying the previous instantiation policy")
   121  
   122  			badUpgrade := LSCCOperation{
   123  				Operation: "upgrade",
   124  				ChannelID: "testchannel",
   125  				Name:      "fakecc",
   126  				Version:   "wrongsubmitter",
   127  				InstantiationOrgs: []*nwo.Organization{
   128  					network.Organization("Org2"),
   129  				},
   130  			}
   131  
   132  			ordererclient.Broadcast(network, orderer, badUpgrade.Tx(network.PeerUserSigner(org2Peer, "Admin")))
   133  
   134  			nwo.WaitUntilEqualLedgerHeight(network, "testchannel", 4, org1Peer)
   135  			Expect(ListInstantiatedLegacy(network, org1Peer, "testchannel")).NotTo(gbytes.Say("Name: fakecc, Version: wrongsubmitter"))
   136  
   137  			By("upgrading while satisfying the previous instantiation policy")
   138  
   139  			goodUpgrade := LSCCOperation{
   140  				Operation: "upgrade",
   141  				ChannelID: "testchannel",
   142  				Name:      "fakecc",
   143  				Version:   "rightsubmitter",
   144  				InstantiationOrgs: []*nwo.Organization{
   145  					network.Organization("Org1"),
   146  				},
   147  			}
   148  
   149  			ordererclient.Broadcast(network, orderer, goodUpgrade.Tx(network.PeerUserSigner(org1Peer, "Admin")))
   150  
   151  			nwo.WaitUntilEqualLedgerHeight(network, "testchannel", 5, org1Peer)
   152  			Expect(ListInstantiatedLegacy(network, org1Peer, "testchannel")).To(gbytes.Say("Name: fakecc, Version: rightsubmitter"))
   153  		})
   154  	})
   155  })
   156  
   157  func ListInstantiatedLegacy(n *nwo.Network, p *nwo.Peer, channel string) *gbytes.Buffer {
   158  	sess, err := n.PeerAdminSession(p, commands.ChaincodeListInstantiatedLegacy{
   159  		ChannelID:  channel,
   160  		ClientAuth: n.ClientAuthRequired,
   161  	})
   162  	Expect(err).NotTo(HaveOccurred())
   163  	Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
   164  	return sess.Buffer()
   165  }
   166  
   167  type LSCCOperation struct {
   168  	Operation         string
   169  	ChannelID         string
   170  	Name              string
   171  	Version           string
   172  	InstantiationOrgs []*nwo.Organization
   173  }
   174  
   175  func (lo *LSCCOperation) Tx(signer *nwo.SigningIdentity) *common.Envelope {
   176  	creatorBytes, err := signer.Serialize()
   177  	Expect(err).NotTo(HaveOccurred())
   178  
   179  	var instantiationMSPIDs []string
   180  	for _, org := range lo.InstantiationOrgs {
   181  		instantiationMSPIDs = append(instantiationMSPIDs, org.MSPID)
   182  	}
   183  	instantiationPolicy := policydsl.SignedByAnyMember(instantiationMSPIDs)
   184  
   185  	nonce, err := time.Now().MarshalBinary()
   186  	Expect(err).NotTo(HaveOccurred())
   187  
   188  	timestamp, err := ptypes.TimestampProto(time.Now().UTC())
   189  	Expect(err).NotTo(HaveOccurred())
   190  
   191  	hasher := sha256.New()
   192  	hasher.Write(nonce)
   193  	hasher.Write(creatorBytes)
   194  	txid := hex.EncodeToString(hasher.Sum(nil))
   195  
   196  	signatureHeaderBytes := protoMarshal(&common.SignatureHeader{
   197  		Creator: creatorBytes,
   198  		Nonce:   nonce,
   199  	})
   200  
   201  	channelHeaderBytes := protoMarshal(&common.ChannelHeader{
   202  		ChannelId: lo.ChannelID,
   203  		Extension: protoMarshal(&peer.ChaincodeHeaderExtension{
   204  			ChaincodeId: &peer.ChaincodeID{
   205  				Name: "lscc",
   206  			},
   207  		}),
   208  		Timestamp: timestamp,
   209  		TxId:      txid,
   210  		Type:      int32(common.HeaderType_ENDORSER_TRANSACTION),
   211  	})
   212  
   213  	chaincodeDataBytes := protoMarshal(&peer.ChaincodeData{
   214  		Data:                []byte("a-big-bunch-of-fakery"),
   215  		Id:                  []byte("a-friendly-fake-chaincode"),
   216  		Escc:                "escc",
   217  		Vscc:                "vscc",
   218  		Name:                lo.Name,
   219  		Version:             lo.Version,
   220  		InstantiationPolicy: instantiationPolicy,
   221  		Policy:              nil, // EndorsementPolicy deliberately left nil
   222  	})
   223  
   224  	proposalPayloadBytes := protoMarshal(&peer.ChaincodeProposalPayload{
   225  		Input: protoMarshal(&peer.ChaincodeInvocationSpec{
   226  			ChaincodeSpec: &peer.ChaincodeSpec{
   227  				Input: &peer.ChaincodeInput{
   228  					Args: [][]byte{
   229  						[]byte(lo.Operation),
   230  						[]byte(lo.ChannelID),
   231  						protoMarshal(&peer.ChaincodeDeploymentSpec{
   232  							ChaincodeSpec: &peer.ChaincodeSpec{
   233  								ChaincodeId: &peer.ChaincodeID{
   234  									Name:    lo.Name,
   235  									Version: lo.Version,
   236  								},
   237  								Input: &peer.ChaincodeInput{
   238  									Args: [][]byte{[]byte("bogus-init-arg")},
   239  								},
   240  								Type: peer.ChaincodeSpec_GOLANG,
   241  							},
   242  						}),
   243  						{}, // Endorsement policy bytes deliberately empty
   244  						[]byte("escc"),
   245  						[]byte("vscc"),
   246  					},
   247  				},
   248  				Type: peer.ChaincodeSpec_GOLANG,
   249  			},
   250  		}),
   251  	})
   252  
   253  	propHash := sha256.New()
   254  	propHash.Write(channelHeaderBytes)
   255  	propHash.Write(signatureHeaderBytes)
   256  	propHash.Write(proposalPayloadBytes)
   257  	proposalHash := propHash.Sum(nil)[:]
   258  
   259  	proposalResponsePayloadBytes := protoMarshal(&peer.ProposalResponsePayload{
   260  		ProposalHash: proposalHash,
   261  		Extension: protoMarshal(&peer.ChaincodeAction{
   262  			ChaincodeId: &peer.ChaincodeID{
   263  				Name:    "lscc",
   264  				Version: "syscc",
   265  			},
   266  			Events: protoMarshal(&peer.ChaincodeEvent{
   267  				ChaincodeId: "lscc",
   268  				EventName:   lo.Operation,
   269  				Payload: protoMarshal(&peer.LifecycleEvent{
   270  					ChaincodeName: lo.Name,
   271  				}),
   272  			}),
   273  			Response: &peer.Response{
   274  				Payload: chaincodeDataBytes,
   275  				Status:  200,
   276  			},
   277  			Results: protoMarshal(&rwset.TxReadWriteSet{
   278  				DataModel: rwset.TxReadWriteSet_KV,
   279  				NsRwset: []*rwset.NsReadWriteSet{
   280  					{
   281  						Namespace: "lscc",
   282  						Rwset: protoMarshal(&kvrwset.KVRWSet{
   283  							Writes: []*kvrwset.KVWrite{
   284  								{
   285  									Key:   lo.Name,
   286  									Value: chaincodeDataBytes,
   287  								},
   288  							},
   289  						}),
   290  					},
   291  					{
   292  						Namespace: lo.Name,
   293  						Rwset: protoMarshal(&kvrwset.KVRWSet{
   294  							Writes: []*kvrwset.KVWrite{
   295  								{
   296  									Key:   "bogus-key",
   297  									Value: []byte("bogus-value"),
   298  								},
   299  							},
   300  						}),
   301  					},
   302  				},
   303  			}),
   304  		}),
   305  	})
   306  
   307  	endorsementSignature, err := signer.Sign(append(proposalResponsePayloadBytes, creatorBytes...))
   308  	Expect(err).NotTo(HaveOccurred())
   309  
   310  	payloadBytes := protoMarshal(&common.Payload{
   311  		Header: &common.Header{
   312  			ChannelHeader:   channelHeaderBytes,
   313  			SignatureHeader: signatureHeaderBytes,
   314  		},
   315  		Data: protoMarshal(&peer.Transaction{
   316  			Actions: []*peer.TransactionAction{
   317  				{
   318  					Header: signatureHeaderBytes,
   319  					Payload: protoMarshal(&peer.ChaincodeActionPayload{
   320  						ChaincodeProposalPayload: proposalPayloadBytes,
   321  						Action: &peer.ChaincodeEndorsedAction{
   322  							ProposalResponsePayload: proposalResponsePayloadBytes,
   323  							Endorsements: []*peer.Endorsement{
   324  								{
   325  									Endorser:  creatorBytes,
   326  									Signature: endorsementSignature,
   327  								},
   328  							},
   329  						},
   330  					}),
   331  				},
   332  			},
   333  		}),
   334  	})
   335  
   336  	envSignature, err := signer.Sign(payloadBytes)
   337  	Expect(err).NotTo(HaveOccurred())
   338  
   339  	return &common.Envelope{
   340  		Payload:   payloadBytes,
   341  		Signature: envSignature,
   342  	}
   343  }
   344  
   345  func protoMarshal(msg proto.Message) []byte {
   346  	b, err := proto.Marshal(msg)
   347  	Expect(err).NotTo(HaveOccurred())
   348  	return b
   349  }