github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/common/validation/statebased/validator_keylevel_test.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package statebased
     8  
     9  import (
    10  	"fmt"
    11  	"testing"
    12  
    13  	"github.com/hechain20/hechain/common/errors"
    14  	"github.com/hechain20/hechain/core/ledger"
    15  	"github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/rwsetutil"
    16  	"github.com/hechain20/hechain/protoutil"
    17  	"github.com/hyperledger/fabric-protos-go/common"
    18  	pb "github.com/hyperledger/fabric-protos-go/peer"
    19  	"github.com/stretchr/testify/require"
    20  )
    21  
    22  type mockPolicyEvaluator struct {
    23  	EvaluateRV          error
    24  	EvaluateResByPolicy map[string]error
    25  }
    26  
    27  func (m *mockPolicyEvaluator) Evaluate(policyBytes []byte, signatureSet []*protoutil.SignedData) error {
    28  	if res, ok := m.EvaluateResByPolicy[string(policyBytes)]; ok {
    29  		return res
    30  	}
    31  
    32  	return m.EvaluateRV
    33  }
    34  
    35  func buildBlockWithTxs(txs ...[]byte) *common.Block {
    36  	return &common.Block{
    37  		Header: &common.BlockHeader{
    38  			Number: 1,
    39  		},
    40  		Data: &common.BlockData{
    41  			Data: txs,
    42  		},
    43  	}
    44  }
    45  
    46  func buildTXWithRwset(rws []byte) []byte {
    47  	return protoutil.MarshalOrPanic(&common.Envelope{
    48  		Payload: protoutil.MarshalOrPanic(
    49  			&common.Payload{
    50  				Data: protoutil.MarshalOrPanic(
    51  					&pb.Transaction{
    52  						Actions: []*pb.TransactionAction{
    53  							{
    54  								Payload: protoutil.MarshalOrPanic(&pb.ChaincodeActionPayload{
    55  									Action: &pb.ChaincodeEndorsedAction{
    56  										ProposalResponsePayload: protoutil.MarshalOrPanic(
    57  											&pb.ProposalResponsePayload{
    58  												Extension: protoutil.MarshalOrPanic(&pb.ChaincodeAction{Results: rws}),
    59  											},
    60  										),
    61  									},
    62  								}),
    63  							},
    64  						},
    65  					},
    66  				),
    67  			},
    68  		),
    69  	})
    70  }
    71  
    72  func rwsetBytes(t *testing.T, cc string) []byte {
    73  	rwsb := rwsetutil.NewRWSetBuilder()
    74  	rwsb.AddToWriteSet(cc, "key", []byte("value"))
    75  	rws := rwsb.GetTxReadWriteSet()
    76  	rwsetbytes, err := rws.ToProtoBytes()
    77  	require.NoError(t, err)
    78  
    79  	return rwsetbytes
    80  }
    81  
    82  func TestKeylevelValidation(t *testing.T) {
    83  	t.Parallel()
    84  
    85  	// Scenario: we validate a transaction that writes
    86  	// to a key that contains key-level validation params.
    87  	// We simulate policy check success and failure
    88  
    89  	vpMetadataKey := pb.MetaDataKeys_VALIDATION_PARAMETER.String()
    90  	mr := &mockState{GetStateMetadataRv: map[string][]byte{vpMetadataKey: []byte("EP")}, GetPrivateDataMetadataByHashRv: map[string][]byte{vpMetadataKey: []byte("EP")}}
    91  	ms := &mockStateFetcher{FetchStateRv: mr}
    92  	pm := &KeyLevelValidationParameterManagerImpl{PolicyTranslator: &mockTranslator{}, StateFetcher: ms}
    93  	pe := &mockPolicyEvaluator{}
    94  	validator := NewKeyLevelValidator(NewV13Evaluator(pe, pm), pm)
    95  
    96  	rwsb := rwsetBytes(t, "cc")
    97  	prp := []byte("barf")
    98  	block := buildBlockWithTxs(buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")), buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")))
    99  
   100  	validator.PreValidate(1, block)
   101  
   102  	endorsements := []*pb.Endorsement{
   103  		{
   104  			Signature: []byte("signature"),
   105  			Endorser:  []byte("endorser"),
   106  		},
   107  	}
   108  
   109  	go func() {
   110  		validator.PostValidate("cc", 1, 0, fmt.Errorf(""))
   111  	}()
   112  
   113  	err := validator.Validate("cc", 1, 1, rwsb, prp, []byte("CCEP"), endorsements)
   114  	require.NoError(t, err)
   115  
   116  	pe.EvaluateRV = fmt.Errorf("policy evaluation error")
   117  
   118  	err = validator.Validate("cc", 1, 1, rwsb, prp, []byte("CCEP"), endorsements)
   119  	require.Error(t, err)
   120  	require.IsType(t, &errors.VSCCEndorsementPolicyError{}, err)
   121  }
   122  
   123  func TestKeylevelValidationPvtData(t *testing.T) {
   124  	t.Parallel()
   125  
   126  	// Scenario: we validate a transaction that writes
   127  	// to a pvt key that contains key-level validation params.
   128  	// We simulate policy check success and failure
   129  
   130  	vpMetadataKey := pb.MetaDataKeys_VALIDATION_PARAMETER.String()
   131  	mr := &mockState{GetStateMetadataRv: map[string][]byte{vpMetadataKey: []byte("EP")}, GetPrivateDataMetadataByHashRv: map[string][]byte{vpMetadataKey: []byte("EP")}}
   132  	ms := &mockStateFetcher{FetchStateRv: mr}
   133  	pm := &KeyLevelValidationParameterManagerImpl{PolicyTranslator: &mockTranslator{}, StateFetcher: ms}
   134  	pe := &mockPolicyEvaluator{}
   135  	validator := NewKeyLevelValidator(NewV13Evaluator(pe, pm), pm)
   136  
   137  	rwsbu := rwsetutil.NewRWSetBuilder()
   138  	rwsbu.AddToPvtAndHashedWriteSet("cc", "coll", "key", []byte("value"))
   139  	rws := rwsbu.GetTxReadWriteSet()
   140  	rwsb, err := rws.ToProtoBytes()
   141  	require.NoError(t, err)
   142  	prp := []byte("barf")
   143  	block := buildBlockWithTxs(buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")), buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")))
   144  
   145  	validator.PreValidate(1, block)
   146  
   147  	go func() {
   148  		validator.PostValidate("cc", 1, 0, fmt.Errorf(""))
   149  	}()
   150  
   151  	err = validator.Validate("cc", 1, 1, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   152  	require.NoError(t, err)
   153  
   154  	pe.EvaluateRV = fmt.Errorf("policy evaluation error")
   155  
   156  	err = validator.Validate("cc", 1, 1, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   157  	require.Error(t, err)
   158  	require.IsType(t, &errors.VSCCEndorsementPolicyError{}, err)
   159  }
   160  
   161  func TestKeylevelValidationMetaUpdate(t *testing.T) {
   162  	t.Parallel()
   163  
   164  	// Scenario: we validate a transaction that updates
   165  	// the key-level validation parameters for a key.
   166  	// We simulate policy check success and failure
   167  
   168  	vpMetadataKey := pb.MetaDataKeys_VALIDATION_PARAMETER.String()
   169  	mr := &mockState{GetStateMetadataRv: map[string][]byte{vpMetadataKey: []byte("EP")}, GetPrivateDataMetadataByHashRv: map[string][]byte{vpMetadataKey: []byte("EP")}}
   170  	ms := &mockStateFetcher{FetchStateRv: mr}
   171  	pm := &KeyLevelValidationParameterManagerImpl{PolicyTranslator: &mockTranslator{}, StateFetcher: ms}
   172  	pe := &mockPolicyEvaluator{}
   173  	validator := NewKeyLevelValidator(NewV13Evaluator(pe, pm), pm)
   174  
   175  	rwsbu := rwsetutil.NewRWSetBuilder()
   176  	rwsbu.AddToMetadataWriteSet("cc", "key", map[string][]byte{})
   177  	rws := rwsbu.GetTxReadWriteSet()
   178  	rwsb, err := rws.ToProtoBytes()
   179  	require.NoError(t, err)
   180  	prp := []byte("barf")
   181  	block := buildBlockWithTxs(buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")), buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")))
   182  
   183  	validator.PreValidate(1, block)
   184  
   185  	go func() {
   186  		validator.PostValidate("cc", 1, 0, fmt.Errorf(""))
   187  	}()
   188  
   189  	err = validator.Validate("cc", 1, 1, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   190  	require.NoError(t, err)
   191  
   192  	pe.EvaluateRV = fmt.Errorf("policy evaluation error")
   193  
   194  	err = validator.Validate("cc", 1, 1, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   195  	require.Error(t, err)
   196  	require.IsType(t, &errors.VSCCEndorsementPolicyError{}, err)
   197  }
   198  
   199  func TestKeylevelValidationPvtMetaUpdate(t *testing.T) {
   200  	t.Parallel()
   201  
   202  	// Scenario: we validate a transaction that updates
   203  	// the key-level validation parameters for a pvt key.
   204  	// We simulate policy check success and failure
   205  
   206  	vpMetadataKey := pb.MetaDataKeys_VALIDATION_PARAMETER.String()
   207  	mr := &mockState{GetStateMetadataRv: map[string][]byte{vpMetadataKey: []byte("EP")}, GetPrivateDataMetadataByHashRv: map[string][]byte{vpMetadataKey: []byte("EP")}}
   208  	ms := &mockStateFetcher{FetchStateRv: mr}
   209  	pm := &KeyLevelValidationParameterManagerImpl{PolicyTranslator: &mockTranslator{}, StateFetcher: ms}
   210  	pe := &mockPolicyEvaluator{}
   211  	validator := NewKeyLevelValidator(NewV13Evaluator(pe, pm), pm)
   212  
   213  	rwsbu := rwsetutil.NewRWSetBuilder()
   214  	rwsbu.AddToHashedMetadataWriteSet("cc", "coll", "key", map[string][]byte{})
   215  	rws := rwsbu.GetTxReadWriteSet()
   216  	rwsb, err := rws.ToProtoBytes()
   217  	require.NoError(t, err)
   218  	prp := []byte("barf")
   219  	block := buildBlockWithTxs(buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")), buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")))
   220  
   221  	validator.PreValidate(1, block)
   222  
   223  	go func() {
   224  		validator.PostValidate("cc", 1, 0, fmt.Errorf(""))
   225  	}()
   226  
   227  	err = validator.Validate("cc", 1, 1, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   228  	require.NoError(t, err)
   229  
   230  	pe.EvaluateRV = fmt.Errorf("policy evaluation error")
   231  
   232  	err = validator.Validate("cc", 1, 1, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   233  	require.Error(t, err)
   234  	require.IsType(t, &errors.VSCCEndorsementPolicyError{}, err)
   235  }
   236  
   237  func TestKeylevelValidationPolicyRetrievalFailure(t *testing.T) {
   238  	t.Parallel()
   239  
   240  	// Scenario: we validate a transaction that updates
   241  	// the key-level validation parameters for a key.
   242  	// we simulate the case where we fail to retrieve
   243  	// the validation parameters from the ledger.
   244  
   245  	mr := &mockState{GetStateMetadataErr: fmt.Errorf("metadata retrieval failure")}
   246  	ms := &mockStateFetcher{FetchStateRv: mr}
   247  	pm := &KeyLevelValidationParameterManagerImpl{PolicyTranslator: &mockTranslator{}, StateFetcher: ms}
   248  	validator := NewKeyLevelValidator(NewV13Evaluator(&mockPolicyEvaluator{}, pm), pm)
   249  
   250  	rwsb := rwsetBytes(t, "cc")
   251  	prp := []byte("barf")
   252  	block := buildBlockWithTxs(buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")), buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")))
   253  
   254  	validator.PreValidate(1, block)
   255  
   256  	go func() {
   257  		validator.PostValidate("cc", 1, 0, fmt.Errorf(""))
   258  	}()
   259  
   260  	err := validator.Validate("cc", 1, 1, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   261  	require.Error(t, err)
   262  	require.IsType(t, &errors.VSCCExecutionFailureError{}, err)
   263  }
   264  
   265  func TestKeylevelValidationLedgerFailures(t *testing.T) {
   266  	// Scenario: we validate a transaction that updates
   267  	// the key-level validation parameters for a key.
   268  	// we simulate the case where we fail to retrieve
   269  	// the validation parameters from the ledger with
   270  	// both deterministic and non-deterministic errors
   271  
   272  	rwsb := rwsetBytes(t, "cc")
   273  	prp := []byte("barf")
   274  
   275  	t.Run("CollConfigNotDefinedError", func(t *testing.T) {
   276  		mr := &mockState{GetStateMetadataErr: &ledger.CollConfigNotDefinedError{Ns: "mycc"}}
   277  		ms := &mockStateFetcher{FetchStateRv: mr}
   278  		pm := &KeyLevelValidationParameterManagerImpl{PolicyTranslator: &mockTranslator{}, StateFetcher: ms}
   279  		validator := NewKeyLevelValidator(NewV13Evaluator(&mockPolicyEvaluator{}, pm), pm)
   280  
   281  		err := validator.Validate("cc", 1, 0, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   282  		require.NoError(t, err)
   283  	})
   284  
   285  	t.Run("InvalidCollNameError", func(t *testing.T) {
   286  		mr := &mockState{GetStateMetadataErr: &ledger.InvalidCollNameError{Ns: "mycc", Coll: "mycoll"}}
   287  		ms := &mockStateFetcher{FetchStateRv: mr}
   288  		pm := &KeyLevelValidationParameterManagerImpl{PolicyTranslator: &mockTranslator{}, StateFetcher: ms}
   289  		validator := NewKeyLevelValidator(NewV13Evaluator(&mockPolicyEvaluator{}, pm), pm)
   290  
   291  		err := validator.Validate("cc", 1, 0, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   292  		require.NoError(t, err)
   293  	})
   294  
   295  	t.Run("I/O error", func(t *testing.T) {
   296  		mr := &mockState{GetStateMetadataErr: fmt.Errorf("some I/O error")}
   297  		ms := &mockStateFetcher{FetchStateRv: mr}
   298  		pm := &KeyLevelValidationParameterManagerImpl{PolicyTranslator: &mockTranslator{}, StateFetcher: ms}
   299  		validator := NewKeyLevelValidator(NewV13Evaluator(&mockPolicyEvaluator{}, pm), pm)
   300  
   301  		err := validator.Validate("cc", 1, 0, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   302  		require.Error(t, err)
   303  		require.IsType(t, &errors.VSCCExecutionFailureError{}, err)
   304  	})
   305  }
   306  
   307  func TestCCEPValidation(t *testing.T) {
   308  	t.Parallel()
   309  
   310  	// Scenario: we validate a transaction that doesn't
   311  	// touch any key with a state-based endorsement policy;
   312  	// we expect to check the normal cc-endorsement policy.
   313  
   314  	mr := &mockState{GetStateMetadataRv: map[string][]byte{}, GetPrivateDataMetadataByHashRv: map[string][]byte{}}
   315  	ms := &mockStateFetcher{FetchStateRv: mr}
   316  	pm := &KeyLevelValidationParameterManagerImpl{PolicyTranslator: &mockTranslator{}, StateFetcher: ms}
   317  	pe := &mockPolicyEvaluator{}
   318  	validator := NewKeyLevelValidator(NewV13Evaluator(pe, pm), pm)
   319  
   320  	rwsbu := rwsetutil.NewRWSetBuilder()
   321  	rwsbu.AddToWriteSet("cc", "key", []byte("value"))
   322  	rwsbu.AddToWriteSet("cc", "key1", []byte("value"))
   323  	rwsbu.AddToReadSet("cc", "readkey", nil)
   324  	rwsbu.AddToHashedReadSet("cc", "coll", "readpvtkey", nil)
   325  	rws := rwsbu.GetTxReadWriteSet()
   326  	rwsb, err := rws.ToProtoBytes()
   327  	require.NoError(t, err)
   328  	prp := []byte("barf")
   329  	block := buildBlockWithTxs(buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")), buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")))
   330  
   331  	validator.PreValidate(1, block)
   332  
   333  	go func() {
   334  		validator.PostValidate("cc", 1, 0, fmt.Errorf(""))
   335  	}()
   336  
   337  	err = validator.Validate("cc", 1, 1, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   338  	require.NoError(t, err)
   339  
   340  	pe.EvaluateRV = fmt.Errorf("policy evaluation error")
   341  
   342  	err = validator.Validate("cc", 1, 1, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   343  	require.Error(t, err)
   344  	require.IsType(t, &errors.VSCCEndorsementPolicyError{}, err)
   345  }
   346  
   347  func TestCCEPValidationReads(t *testing.T) {
   348  	t.Parallel()
   349  
   350  	// Scenario: we validate a transaction that doesn't
   351  	// touch any key with a state-based endorsement policy;
   352  	// we expect to check the normal cc-endorsement policy.
   353  
   354  	mr := &mockState{GetStateMetadataRv: map[string][]byte{}, GetPrivateDataMetadataByHashRv: map[string][]byte{}}
   355  	ms := &mockStateFetcher{FetchStateRv: mr}
   356  	pm := &KeyLevelValidationParameterManagerImpl{PolicyTranslator: &mockTranslator{}, StateFetcher: ms}
   357  	pe := &mockPolicyEvaluator{}
   358  	validator := NewKeyLevelValidator(NewV13Evaluator(pe, pm), pm)
   359  
   360  	rwsbu := rwsetutil.NewRWSetBuilder()
   361  	rwsbu.AddToReadSet("cc", "readkey", nil)
   362  	rws := rwsbu.GetTxReadWriteSet()
   363  	rwsb, err := rws.ToProtoBytes()
   364  	require.NoError(t, err)
   365  	prp := []byte("barf")
   366  	block := buildBlockWithTxs(buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")), buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")))
   367  
   368  	validator.PreValidate(1, block)
   369  
   370  	go func() {
   371  		validator.PostValidate("cc", 1, 0, fmt.Errorf(""))
   372  	}()
   373  
   374  	err = validator.Validate("cc", 1, 1, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   375  	require.NoError(t, err)
   376  
   377  	pe.EvaluateRV = fmt.Errorf("policy evaluation error")
   378  
   379  	err = validator.Validate("cc", 1, 1, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   380  	require.Error(t, err)
   381  	require.IsType(t, &errors.VSCCEndorsementPolicyError{}, err)
   382  }
   383  
   384  func TestOnlySBEPChecked(t *testing.T) {
   385  	t.Parallel()
   386  
   387  	// Scenario: we ensure that as long as there is one key that
   388  	// requires state-based endorsement, we only check that policy
   389  	// and we do not check the cc-EP. We check that by setting up the
   390  	// policy evaluator mock into returning an error for all policies
   391  	// but the state-based one, and expect successful evaluation
   392  
   393  	vpMetadataKey := pb.MetaDataKeys_VALIDATION_PARAMETER.String()
   394  	mr := &mockState{GetStateMetadataRv: map[string][]byte{vpMetadataKey: []byte("SBEP")}}
   395  	ms := &mockStateFetcher{FetchStateRv: mr}
   396  	pm := &KeyLevelValidationParameterManagerImpl{PolicyTranslator: &mockTranslator{}, StateFetcher: ms}
   397  	pe := &mockPolicyEvaluator{}
   398  	validator := NewKeyLevelValidator(NewV13Evaluator(pe, pm), pm)
   399  
   400  	rwsb := rwsetBytes(t, "cc")
   401  	prp := []byte("barf")
   402  	block := buildBlockWithTxs(buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")), buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")))
   403  
   404  	validator.PreValidate(1, block)
   405  
   406  	go func() {
   407  		validator.PostValidate("cc", 1, 0, fmt.Errorf(""))
   408  	}()
   409  
   410  	pe.EvaluateRV = fmt.Errorf("policy evaluation error")
   411  	pe.EvaluateResByPolicy = map[string]error{
   412  		"SBEP": nil,
   413  	}
   414  
   415  	err := validator.Validate("cc", 1, 1, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   416  	require.NoError(t, err)
   417  
   418  	// we also test with a read-write set that has a read as well as a write
   419  	rwsbu := rwsetutil.NewRWSetBuilder()
   420  	rwsbu.AddToWriteSet("cc", "key", []byte("value"))
   421  	rwsbu.AddToReadSet("cc", "key", nil)
   422  	rws := rwsbu.GetTxReadWriteSet()
   423  	rwsb, _ = rws.ToProtoBytes()
   424  
   425  	err = validator.Validate("cc", 1, 1, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   426  	require.NoError(t, err)
   427  }
   428  
   429  func TestCCEPValidationPvtReads(t *testing.T) {
   430  	t.Parallel()
   431  
   432  	// Scenario: we validate a transaction that doesn't
   433  	// touch any key with a state-based endorsement policy;
   434  	// we expect to check the normal cc-endorsement policy.
   435  
   436  	mr := &mockState{GetStateMetadataRv: map[string][]byte{}, GetPrivateDataMetadataByHashRv: map[string][]byte{}}
   437  	ms := &mockStateFetcher{FetchStateRv: mr}
   438  	pm := &KeyLevelValidationParameterManagerImpl{PolicyTranslator: &mockTranslator{}, StateFetcher: ms}
   439  	pe := &mockPolicyEvaluator{}
   440  	validator := NewKeyLevelValidator(NewV13Evaluator(pe, pm), pm)
   441  
   442  	rwsbu := rwsetutil.NewRWSetBuilder()
   443  	rwsbu.AddToHashedReadSet("cc", "coll", "readpvtkey", nil)
   444  	rws := rwsbu.GetTxReadWriteSet()
   445  	rwsb, err := rws.ToProtoBytes()
   446  	require.NoError(t, err)
   447  	prp := []byte("barf")
   448  	block := buildBlockWithTxs(buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")), buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")))
   449  
   450  	validator.PreValidate(1, block)
   451  
   452  	go func() {
   453  		validator.PostValidate("cc", 1, 0, fmt.Errorf(""))
   454  	}()
   455  
   456  	err = validator.Validate("cc", 1, 1, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   457  	require.NoError(t, err)
   458  
   459  	pe.EvaluateRV = fmt.Errorf("policy evaluation error")
   460  
   461  	err = validator.Validate("cc", 1, 1, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   462  	require.Error(t, err)
   463  	require.IsType(t, &errors.VSCCEndorsementPolicyError{}, err)
   464  }
   465  
   466  func TestKeylevelValidationFailure(t *testing.T) {
   467  	t.Parallel()
   468  
   469  	// Scenario: we validate a transaction that writes
   470  	// to a key that contains key-level validation params.
   471  	// Validation fails because the block contains a previous
   472  	// transaction that updates the key-level validation params
   473  	// for that very same key.
   474  
   475  	vpMetadataKey := pb.MetaDataKeys_VALIDATION_PARAMETER.String()
   476  	mr := &mockState{GetStateMetadataRv: map[string][]byte{vpMetadataKey: []byte("EP")}, GetPrivateDataMetadataByHashRv: map[string][]byte{vpMetadataKey: []byte("EP")}}
   477  	ms := &mockStateFetcher{FetchStateRv: mr}
   478  	pm := &KeyLevelValidationParameterManagerImpl{PolicyTranslator: &mockTranslator{}, StateFetcher: ms}
   479  	validator := NewKeyLevelValidator(NewV13Evaluator(&mockPolicyEvaluator{}, pm), pm)
   480  
   481  	rwsb := rwsetBytes(t, "cc")
   482  	prp := []byte("barf")
   483  	block := buildBlockWithTxs(buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")), buildTXWithRwset(rwsetUpdatingMetadataFor("cc", "key")))
   484  
   485  	validator.PreValidate(1, block)
   486  
   487  	go func() {
   488  		validator.PostValidate("cc", 1, 0, nil)
   489  	}()
   490  
   491  	err := validator.Validate("cc", 1, 1, rwsb, prp, []byte("CCEP"), []*pb.Endorsement{})
   492  	require.Error(t, err)
   493  	require.IsType(t, &errors.VSCCEndorsementPolicyError{}, err)
   494  }