Skip to content

Commit

Permalink
Merge changes I14846f8d,I7aec7028
Browse files Browse the repository at this point in the history
* changes:
  FAB-16286 IT with forged RWset for LSCC IP failure
  FAB-16286 Split raft Broadcast/Deliver IT tool out
  • Loading branch information
Jason Yellick authored and Gerrit Code Review committed Nov 18, 2019
2 parents 2e4d92e + a0ab031 commit fd55ee2
Show file tree
Hide file tree
Showing 5 changed files with 494 additions and 117 deletions.
365 changes: 365 additions & 0 deletions integration/e2e/instantiation_policy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,365 @@
/*
Copyright IBM Corp All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package e2e

import (
"crypto/sha256"
"encoding/hex"
"io/ioutil"
"os"
"syscall"
"time"

docker "github.com/fsouza/go-dockerclient"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes"
"github.com/hyperledger/fabric-protos-go/common"
"github.com/hyperledger/fabric-protos-go/ledger/rwset"
"github.com/hyperledger/fabric-protos-go/ledger/rwset/kvrwset"
"github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric/cmd/common/signer"
"github.com/hyperledger/fabric/common/cauthdsl"
"github.com/hyperledger/fabric/integration/nwo"
"github.com/hyperledger/fabric/integration/nwo/commands"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
"github.com/onsi/gomega/gexec"
"github.com/tedsuo/ifrit"
)

var _ = Describe("InstantiationPolicy", func() {
var (
testDir string
client *docker.Client
network *nwo.Network
process ifrit.Process
)

BeforeEach(func() {
var err error
testDir, err = ioutil.TempDir("", "e2e")
Expect(err).NotTo(HaveOccurred())

client, err = docker.NewClientFromEnv()
Expect(err).NotTo(HaveOccurred())
})

AfterEach(func() {
if process != nil {
process.Signal(syscall.SIGTERM)
Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive())
}
if network != nil {
network.Cleanup()
}
os.RemoveAll(testDir)
})

Describe("single node etcdraft network with single peer", func() {
BeforeEach(func() {
config := nwo.MinimalRaft()
config.Profiles[1].Organizations = []string{"Org1", "Org2"}
network = nwo.New(config, testDir, client, StartPort(), components)
network.GenerateConfigTree()
network.Bootstrap()

networkRunner := network.NetworkGroupRunner()
process = ifrit.Invoke(networkRunner)
Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed())
})

It("honors the instantiation policy", func() {
orderer := network.Orderer("orderer")

org1Peer := network.Peer("Org1", "peer0")
org2Peer := network.Peer("Org2", "peer0")

network.CreateAndJoinChannel(orderer, "testchannel")

By("attempting to deploy with an unsatisfied instantiation policy")

goodDeploy := LSCCOperation{
Operation: "deploy",
ChannelID: "testchannel",
Name: "fakecc",
Version: "badip",
InstantiationOrgs: []*nwo.Organization{
network.Organization("Org2"),
},
}

nwo.Broadcast(network, orderer, goodDeploy.Tx(PeerSigner(network, org1Peer)))

nwo.WaitUntilEqualLedgerHeight(network, "testchannel", 2, org1Peer)

Expect(ListInstantiatedLegacy(network, org1Peer, "testchannel")).NotTo(gbytes.Say("Name: fakecc, Version: badip"))

By("attempting to deploy with a satisfied instantiation policy")

badDeploy := LSCCOperation{
Operation: "deploy",
ChannelID: "testchannel",
Name: "fakecc",
Version: "goodip",
InstantiationOrgs: []*nwo.Organization{
network.Organization("Org1"),
},
}

nwo.Broadcast(network, orderer, badDeploy.Tx(PeerSigner(network, org1Peer)))

nwo.WaitUntilEqualLedgerHeight(network, "testchannel", 3, org1Peer)
Expect(ListInstantiatedLegacy(network, org1Peer, "testchannel")).To(gbytes.Say("Name: fakecc, Version: goodip"))

By("upgrading without satisfying the previous instantiation policy")

badUpgrade := LSCCOperation{
Operation: "upgrade",
ChannelID: "testchannel",
Name: "fakecc",
Version: "wrongsubmitter",
InstantiationOrgs: []*nwo.Organization{
network.Organization("Org2"),
},
}

nwo.Broadcast(network, orderer, badUpgrade.Tx(PeerSigner(network, org2Peer)))

nwo.WaitUntilEqualLedgerHeight(network, "testchannel", 4, org1Peer)
Expect(ListInstantiatedLegacy(network, org1Peer, "testchannel")).NotTo(gbytes.Say("Name: fakecc, Version: wrongsubmitter"))

By("upgrading while satisfying the previous instantiation policy")

goodUpgrade := LSCCOperation{
Operation: "upgrade",
ChannelID: "testchannel",
Name: "fakecc",
Version: "rightsubmitter",
InstantiationOrgs: []*nwo.Organization{
network.Organization("Org1"),
},
}

nwo.Broadcast(network, orderer, goodUpgrade.Tx(PeerSigner(network, org1Peer)))

nwo.WaitUntilEqualLedgerHeight(network, "testchannel", 5, org1Peer)
Expect(ListInstantiatedLegacy(network, org1Peer, "testchannel")).To(gbytes.Say("Name: fakecc, Version: rightsubmitter"))
})
})

})

func PeerSigner(n *nwo.Network, p *nwo.Peer) *signer.Signer {
conf := signer.Config{
MSPID: n.Organization(p.Organization).MSPID,
IdentityPath: n.PeerUserCert(p, "Admin"),
KeyPath: n.PeerUserKey(p, "Admin"),
}

signer, err := signer.NewSigner(conf)
Expect(err).NotTo(HaveOccurred())

return signer
}

func MarshalOrPanic(msg proto.Message) []byte {
b, err := proto.Marshal(msg)
if err != nil {
panic(err)
}
return b
}

func ListInstantiatedLegacy(n *nwo.Network, p *nwo.Peer, channel string) *gbytes.Buffer {
sess, err := n.PeerAdminSession(p, commands.ChaincodeListInstantiatedLegacy{
ChannelID: channel,
ClientAuth: n.ClientAuthRequired,
})
Expect(err).NotTo(HaveOccurred())
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
return sess.Buffer()
}

type LSCCOperation struct {
Operation string
ChannelID string
Name string
Version string
InstantiationOrgs []*nwo.Organization
}

func (lo *LSCCOperation) Tx(signer *signer.Signer) *common.Envelope {
creatorBytes, err := signer.Serialize()
Expect(err).NotTo(HaveOccurred())

var instantiationMSPIDs []string
for _, org := range lo.InstantiationOrgs {
instantiationMSPIDs = append(instantiationMSPIDs, org.MSPID)
}
instantiationPolicy := cauthdsl.SignedByAnyMember(instantiationMSPIDs)

nonce, err := time.Now().MarshalBinary()
Expect(err).NotTo(HaveOccurred())

timestamp, err := ptypes.TimestampProto(time.Now().UTC())
Expect(err).NotTo(HaveOccurred())

hasher := sha256.New()
hasher.Write(nonce)
hasher.Write(creatorBytes)
txid := hex.EncodeToString(hasher.Sum(nil))

signatureHeaderBytes := MarshalOrPanic(&common.SignatureHeader{
Creator: creatorBytes,
Nonce: nonce,
})

channelHeaderBytes := MarshalOrPanic(&common.ChannelHeader{
ChannelId: lo.ChannelID,
Extension: MarshalOrPanic(&peer.ChaincodeHeaderExtension{
ChaincodeId: &peer.ChaincodeID{
Name: "lscc",
},
}),
Timestamp: timestamp,
TxId: txid,
Type: int32(common.HeaderType_ENDORSER_TRANSACTION),
})

chaincodeDataBytes := MarshalOrPanic(&peer.ChaincodeData{
Data: []byte("a-big-bunch-of-fakery"),
Id: []byte("a-friendly-fake-chaincode"),
Escc: "escc",
Vscc: "vscc",
Name: lo.Name,
Version: lo.Version,
InstantiationPolicy: instantiationPolicy,
Policy: nil, // EndorsementPolicy deliberately left nil
})

proposalPayloadBytes := MarshalOrPanic(&peer.ChaincodeProposalPayload{
Input: MarshalOrPanic(&peer.ChaincodeInvocationSpec{
ChaincodeSpec: &peer.ChaincodeSpec{
Input: &peer.ChaincodeInput{
Args: [][]byte{
[]byte(lo.Operation),
[]byte(lo.ChannelID),
MarshalOrPanic(&peer.ChaincodeDeploymentSpec{
ChaincodeSpec: &peer.ChaincodeSpec{
ChaincodeId: &peer.ChaincodeID{
Name: lo.Name,
Version: lo.Version,
},
Input: &peer.ChaincodeInput{
Args: [][]byte{[]byte("bogus-init-arg")},
},
Type: peer.ChaincodeSpec_GOLANG,
},
}),
{}, // Endorsement policy bytes deliberately empty
[]byte("escc"),
[]byte("vscc"),
},
},
Type: peer.ChaincodeSpec_GOLANG,
},
}),
})

propHash := sha256.New()
propHash.Write(channelHeaderBytes)
propHash.Write(signatureHeaderBytes)
propHash.Write(proposalPayloadBytes)
proposalHash := propHash.Sum(nil)[:]

proposalResponsePayloadBytes := MarshalOrPanic(&peer.ProposalResponsePayload{
ProposalHash: proposalHash,
Extension: MarshalOrPanic(&peer.ChaincodeAction{
ChaincodeId: &peer.ChaincodeID{
Name: "lscc",
Version: "syscc",
},
Events: MarshalOrPanic(&peer.ChaincodeEvent{
ChaincodeId: "lscc",
EventName: lo.Operation,
Payload: MarshalOrPanic(&peer.LifecycleEvent{
ChaincodeName: lo.Name,
}),
}),
Response: &peer.Response{
Payload: chaincodeDataBytes,
Status: 200,
},
Results: MarshalOrPanic(&rwset.TxReadWriteSet{
DataModel: rwset.TxReadWriteSet_KV,
NsRwset: []*rwset.NsReadWriteSet{
{
Namespace: "lscc",
Rwset: MarshalOrPanic(&kvrwset.KVRWSet{
Writes: []*kvrwset.KVWrite{
{
Key: lo.Name,
Value: chaincodeDataBytes,
},
},
}),
},
{
Namespace: lo.Name,
Rwset: MarshalOrPanic(&kvrwset.KVRWSet{
Writes: []*kvrwset.KVWrite{
{
Key: "bogus-key",
Value: []byte("bogus-value"),
},
},
}),
},
},
}),
}),
})

endorsementSignature, err := signer.Sign(append(proposalResponsePayloadBytes, creatorBytes...))
Expect(err).NotTo(HaveOccurred())

payloadBytes := MarshalOrPanic(&common.Payload{
Header: &common.Header{
ChannelHeader: channelHeaderBytes,
SignatureHeader: signatureHeaderBytes,
},
Data: MarshalOrPanic(&peer.Transaction{
Actions: []*peer.TransactionAction{
{
Header: signatureHeaderBytes,
Payload: MarshalOrPanic(&peer.ChaincodeActionPayload{
ChaincodeProposalPayload: proposalPayloadBytes,
Action: &peer.ChaincodeEndorsedAction{
ProposalResponsePayload: proposalResponsePayloadBytes,
Endorsements: []*peer.Endorsement{
{
Endorser: creatorBytes,
Signature: endorsementSignature,
},
},
},
}),
},
},
}),
})

envSignature, err := signer.Sign(payloadBytes)
Expect(err).NotTo(HaveOccurred())

return &common.Envelope{
Payload: payloadBytes,
Signature: envSignature,
}
}
Loading

0 comments on commit fd55ee2

Please sign in to comment.