github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/core/common/validation/fullflow_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package validation
    18  
    19  import (
    20  	"fmt"
    21  	"math/rand"
    22  	"os"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/hyperledger/fabric/common/util"
    27  	"github.com/hyperledger/fabric/msp"
    28  	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
    29  	"github.com/hyperledger/fabric/msp/mgmt/testtools"
    30  	"github.com/hyperledger/fabric/protos/common"
    31  	"github.com/hyperledger/fabric/protos/peer"
    32  	"github.com/hyperledger/fabric/protos/utils"
    33  )
    34  
    35  func getProposal() (*peer.Proposal, error) {
    36  	cis := &peer.ChaincodeInvocationSpec{
    37  		ChaincodeSpec: &peer.ChaincodeSpec{
    38  			ChaincodeId: &peer.ChaincodeID{Name: "foo"},
    39  			Type:        peer.ChaincodeSpec_GOLANG}}
    40  
    41  	proposal, _, err := utils.CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, util.GetTestChainID(), cis, signerSerialized)
    42  	return proposal, err
    43  }
    44  
    45  func TestGoodPath(t *testing.T) {
    46  	// get a toy proposal
    47  	prop, err := getProposal()
    48  	if err != nil {
    49  		t.Fatalf("getProposal failed, err %s", err)
    50  		return
    51  	}
    52  
    53  	// sign it
    54  	sProp, err := utils.GetSignedProposal(prop, signer)
    55  	if err != nil {
    56  		t.Fatalf("GetSignedProposal failed, err %s", err)
    57  		return
    58  	}
    59  
    60  	// validate it
    61  	_, _, _, err = ValidateProposalMessage(sProp)
    62  	if err != nil {
    63  		t.Fatalf("ValidateProposalMessage failed, err %s", err)
    64  		return
    65  	}
    66  
    67  	response := &peer.Response{Status: 200}
    68  	simRes := []byte("simulation_result")
    69  
    70  	// endorse it to get a proposal response
    71  	presp, err := utils.CreateProposalResponse(prop.Header, prop.Payload, response, simRes, nil, nil, signer)
    72  	if err != nil {
    73  		t.Fatalf("CreateProposalResponse failed, err %s", err)
    74  		return
    75  	}
    76  
    77  	// assemble a transaction from that proposal and endorsement
    78  	tx, err := utils.CreateSignedTx(prop, signer, presp)
    79  	if err != nil {
    80  		t.Fatalf("CreateSignedTx failed, err %s", err)
    81  		return
    82  	}
    83  
    84  	// validate the transaction
    85  	payl, txResult := ValidateTransaction(tx)
    86  	if txResult != peer.TxValidationCode_VALID {
    87  		t.Fatalf("ValidateTransaction failed, err %s", err)
    88  		return
    89  	}
    90  
    91  	txx, err := utils.GetTransaction(payl.Data)
    92  	if err != nil {
    93  		t.Fatalf("GetTransaction failed, err %s", err)
    94  		return
    95  	}
    96  
    97  	act := txx.Actions
    98  
    99  	// expect one single action
   100  	if len(act) != 1 {
   101  		t.Fatalf("Ivalid number of TransactionAction, expected 1, got %d", len(act))
   102  		return
   103  	}
   104  
   105  	// get the payload of the action
   106  	_, simResBack, err := utils.GetPayloads(act[0])
   107  	if err != nil {
   108  		t.Fatalf("GetPayloads failed, err %s", err)
   109  		return
   110  	}
   111  
   112  	// compare it to the original action and expect it to be equal
   113  	if string(simRes) != string(simResBack.Results) {
   114  		t.Fatal("Simulation results are different")
   115  		return
   116  	}
   117  }
   118  
   119  var r *rand.Rand
   120  
   121  func corrupt(bytes []byte) {
   122  	if r == nil {
   123  		r = rand.New(rand.NewSource(time.Now().Unix()))
   124  	}
   125  
   126  	bytes[r.Int31n(int32(len(bytes)))]--
   127  }
   128  
   129  func TestBadProp(t *testing.T) {
   130  	// get a toy proposal
   131  	prop, err := getProposal()
   132  	if err != nil {
   133  		t.Fatalf("getProposal failed, err %s", err)
   134  		return
   135  	}
   136  
   137  	// sign it
   138  	sProp, err := utils.GetSignedProposal(prop, signer)
   139  	if err != nil {
   140  		t.Fatalf("GetSignedProposal failed, err %s", err)
   141  		return
   142  	}
   143  
   144  	// mess with the signature
   145  	corrupt(sProp.Signature)
   146  
   147  	// validate it - it should fail
   148  	_, _, _, err = ValidateProposalMessage(sProp)
   149  	if err == nil {
   150  		t.Fatal("ValidateProposalMessage should have failed")
   151  		return
   152  	}
   153  
   154  	// sign it again
   155  	sProp, err = utils.GetSignedProposal(prop, signer)
   156  	if err != nil {
   157  		t.Fatalf("GetSignedProposal failed, err %s", err)
   158  		return
   159  	}
   160  
   161  	// mess with the message
   162  	corrupt(sProp.ProposalBytes)
   163  
   164  	// validate it - it should fail
   165  	_, _, _, err = ValidateProposalMessage(sProp)
   166  	if err == nil {
   167  		t.Fatal("ValidateProposalMessage should have failed")
   168  		return
   169  	}
   170  
   171  	// get a bad signing identity
   172  	badSigner, err := msp.NewNoopMsp().GetDefaultSigningIdentity()
   173  	if err != nil {
   174  		t.Fatal("Couldn't get noop signer")
   175  		return
   176  	}
   177  
   178  	// sign it again with the bad signer
   179  	sProp, err = utils.GetSignedProposal(prop, badSigner)
   180  	if err != nil {
   181  		t.Fatalf("GetSignedProposal failed, err %s", err)
   182  		return
   183  	}
   184  
   185  	// validate it - it should fail
   186  	_, _, _, err = ValidateProposalMessage(sProp)
   187  	if err == nil {
   188  		t.Fatal("ValidateProposalMessage should have failed")
   189  		return
   190  	}
   191  }
   192  
   193  func TestBadTx(t *testing.T) {
   194  	// get a toy proposal
   195  	prop, err := getProposal()
   196  	if err != nil {
   197  		t.Fatalf("getProposal failed, err %s", err)
   198  		return
   199  	}
   200  
   201  	response := &peer.Response{Status: 200}
   202  	simRes := []byte("simulation_result")
   203  
   204  	// endorse it to get a proposal response
   205  	presp, err := utils.CreateProposalResponse(prop.Header, prop.Payload, response, simRes, nil, nil, signer)
   206  	if err != nil {
   207  		t.Fatalf("CreateProposalResponse failed, err %s", err)
   208  		return
   209  	}
   210  
   211  	// assemble a transaction from that proposal and endorsement
   212  	tx, err := utils.CreateSignedTx(prop, signer, presp)
   213  	if err != nil {
   214  		t.Fatalf("CreateSignedTx failed, err %s", err)
   215  		return
   216  	}
   217  
   218  	// mess with the transaction payload
   219  	corrupt(tx.Payload)
   220  
   221  	// validate the transaction it should fail
   222  	_, txResult := ValidateTransaction(tx)
   223  	if txResult == peer.TxValidationCode_VALID {
   224  		t.Fatal("ValidateTransaction should have failed")
   225  		return
   226  	}
   227  
   228  	// assemble a transaction from that proposal and endorsement
   229  	tx, err = utils.CreateSignedTx(prop, signer, presp)
   230  	if err != nil {
   231  		t.Fatalf("CreateSignedTx failed, err %s", err)
   232  		return
   233  	}
   234  
   235  	// mess with the transaction payload
   236  	corrupt(tx.Signature)
   237  
   238  	// validate the transaction it should fail
   239  	_, txResult = ValidateTransaction(tx)
   240  	if txResult == peer.TxValidationCode_VALID {
   241  		t.Fatal("ValidateTransaction should have failed")
   242  		return
   243  	}
   244  }
   245  
   246  func Test2EndorsersAgree(t *testing.T) {
   247  	// get a toy proposal
   248  	prop, err := getProposal()
   249  	if err != nil {
   250  		t.Fatalf("getProposal failed, err %s", err)
   251  		return
   252  	}
   253  
   254  	response1 := &peer.Response{Status: 200}
   255  	simRes1 := []byte("simulation_result")
   256  
   257  	// endorse it to get a proposal response
   258  	presp1, err := utils.CreateProposalResponse(prop.Header, prop.Payload, response1, simRes1, nil, nil, signer)
   259  	if err != nil {
   260  		t.Fatalf("CreateProposalResponse failed, err %s", err)
   261  		return
   262  	}
   263  
   264  	response2 := &peer.Response{Status: 200}
   265  	simRes2 := []byte("simulation_result")
   266  
   267  	// endorse it to get a proposal response
   268  	presp2, err := utils.CreateProposalResponse(prop.Header, prop.Payload, response2, simRes2, nil, nil, signer)
   269  	if err != nil {
   270  		t.Fatalf("CreateProposalResponse failed, err %s", err)
   271  		return
   272  	}
   273  
   274  	// assemble a transaction from that proposal and endorsement
   275  	tx, err := utils.CreateSignedTx(prop, signer, presp1, presp2)
   276  	if err != nil {
   277  		t.Fatalf("CreateSignedTx failed, err %s", err)
   278  		return
   279  	}
   280  
   281  	// validate the transaction
   282  	_, txResult := ValidateTransaction(tx)
   283  	if txResult != peer.TxValidationCode_VALID {
   284  		t.Fatalf("ValidateTransaction failed, err %s", err)
   285  		return
   286  	}
   287  }
   288  
   289  func Test2EndorsersDisagree(t *testing.T) {
   290  	// get a toy proposal
   291  	prop, err := getProposal()
   292  	if err != nil {
   293  		t.Fatalf("getProposal failed, err %s", err)
   294  		return
   295  	}
   296  
   297  	response1 := &peer.Response{Status: 200}
   298  	simRes1 := []byte("simulation_result1")
   299  
   300  	// endorse it to get a proposal response
   301  	presp1, err := utils.CreateProposalResponse(prop.Header, prop.Payload, response1, simRes1, nil, nil, signer)
   302  	if err != nil {
   303  		t.Fatalf("CreateProposalResponse failed, err %s", err)
   304  		return
   305  	}
   306  
   307  	response2 := &peer.Response{Status: 200}
   308  	simRes2 := []byte("simulation_result2")
   309  
   310  	// endorse it to get a proposal response
   311  	presp2, err := utils.CreateProposalResponse(prop.Header, prop.Payload, response2, simRes2, nil, nil, signer)
   312  	if err != nil {
   313  		t.Fatalf("CreateProposalResponse failed, err %s", err)
   314  		return
   315  	}
   316  
   317  	// assemble a transaction from that proposal and endorsement
   318  	_, err = utils.CreateSignedTx(prop, signer, presp1, presp2)
   319  	if err == nil {
   320  		t.Fatal("CreateSignedTx should have failed")
   321  		return
   322  	}
   323  }
   324  
   325  var signer msp.SigningIdentity
   326  var signerSerialized []byte
   327  
   328  func TestMain(m *testing.M) {
   329  	// setup crypto algorithms
   330  	// setup the MSP manager so that we can sign/verify
   331  	mspMgrConfigDir := "../../../msp/sampleconfig/"
   332  	err := msptesttools.LoadMSPSetupForTesting(mspMgrConfigDir)
   333  	if err != nil {
   334  		fmt.Printf("Could not initialize msp, err %s", err)
   335  		os.Exit(-1)
   336  		return
   337  	}
   338  
   339  	signer, err = mspmgmt.GetLocalMSP().GetDefaultSigningIdentity()
   340  	if err != nil {
   341  		fmt.Println("Could not get signer")
   342  		os.Exit(-1)
   343  		return
   344  	}
   345  
   346  	signerSerialized, err = signer.Serialize()
   347  	if err != nil {
   348  		fmt.Println("Could not serialize identity")
   349  		os.Exit(-1)
   350  		return
   351  	}
   352  
   353  	os.Exit(m.Run())
   354  }