github.com/ahlemtn/fabric@v2.1.1+incompatible/core/peer/configtx_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package peer
     8  
     9  import (
    10  	"io/ioutil"
    11  	"os"
    12  	"testing"
    13  
    14  	"github.com/golang/protobuf/proto"
    15  	"github.com/hyperledger/fabric-protos-go/common"
    16  	"github.com/hyperledger/fabric/bccsp/sw"
    17  	"github.com/hyperledger/fabric/common/capabilities"
    18  	"github.com/hyperledger/fabric/common/channelconfig"
    19  	configtxtest "github.com/hyperledger/fabric/common/configtx/test"
    20  	"github.com/hyperledger/fabric/common/ledger/testutil"
    21  	"github.com/hyperledger/fabric/core/config/configtest"
    22  	"github.com/hyperledger/fabric/core/ledger"
    23  	"github.com/hyperledger/fabric/internal/configtxgen/encoder"
    24  	"github.com/hyperledger/fabric/internal/configtxgen/genesisconfig"
    25  	"github.com/hyperledger/fabric/protoutil"
    26  	"github.com/stretchr/testify/assert"
    27  	"github.com/stretchr/testify/require"
    28  )
    29  
    30  func TestConfigTxCreateLedger(t *testing.T) {
    31  	helper := newTestHelper(t)
    32  	channelID := "testchain1"
    33  	tempdir, err := ioutil.TempDir("", "peer-test")
    34  	require.NoError(t, err, "failed to create temporary directory")
    35  
    36  	ledgerMgr, err := constructLedgerMgrWithTestDefaults(tempdir)
    37  	if err != nil {
    38  		t.Fatalf("Failed to create test environment: %s", err)
    39  	}
    40  
    41  	defer func() {
    42  		ledgerMgr.Close()
    43  		os.RemoveAll(tempdir)
    44  	}()
    45  
    46  	chanConf := helper.sampleChannelConfig(1, true)
    47  	genesisTx := helper.constructGenesisTx(t, channelID, chanConf)
    48  	genesisBlock := helper.constructBlock(genesisTx, 0, nil)
    49  	ledger, err := ledgerMgr.CreateLedger(channelID, genesisBlock)
    50  	assert.NoError(t, err)
    51  
    52  	retrievedchanConf, err := retrievePersistedChannelConfig(ledger)
    53  	assert.NoError(t, err)
    54  	assert.Equal(t, proto.CompactTextString(chanConf), proto.CompactTextString(retrievedchanConf))
    55  }
    56  
    57  func TestConfigTxErrorScenarios(t *testing.T) {
    58  	configTxProcessor := &ConfigTxProcessor{}
    59  	// wrong tx type
    60  	configEnvWrongTxType := &common.ConfigEnvelope{}
    61  	txEnvelope, err := protoutil.CreateSignedEnvelope(common.HeaderType_PEER_ADMIN_OPERATION, "channelID", nil, configEnvWrongTxType, 0, 0)
    62  	require.NoError(t, err)
    63  	err = configTxProcessor.GenerateSimulationResults(txEnvelope, nil, false)
    64  	require.EqualError(t, err, "tx type [PEER_ADMIN_OPERATION] is not expected")
    65  
    66  	// empty channelConfig
    67  	txEnvelope, err = protoutil.CreateSignedEnvelope(common.HeaderType_CONFIG, "channelID", nil, &common.ConfigEnvelope{}, 0, 0)
    68  	require.NoError(t, err)
    69  	err = configTxProcessor.GenerateSimulationResults(txEnvelope, nil, false)
    70  	require.EqualError(t, err, "channel config found nil")
    71  }
    72  
    73  func TestConfigTxUpdateChanConfig(t *testing.T) {
    74  	helper := newTestHelper(t)
    75  	channelID := "testchain1"
    76  	tempdir, err := ioutil.TempDir("", "peer-test")
    77  	require.NoError(t, err, "failed to create temporary directory")
    78  
    79  	ledgerMgr, err := constructLedgerMgrWithTestDefaults(tempdir)
    80  	if err != nil {
    81  		t.Fatalf("Failed to create test environment: %s", err)
    82  	}
    83  
    84  	defer func() {
    85  		ledgerMgr.Close()
    86  		os.RemoveAll(tempdir)
    87  	}()
    88  
    89  	chanConf := helper.sampleChannelConfig(1, true)
    90  	genesisTx := helper.constructGenesisTx(t, channelID, chanConf)
    91  	genesisBlock := helper.constructBlock(genesisTx, 0, nil)
    92  	lgr, err := ledgerMgr.CreateLedger(channelID, genesisBlock)
    93  	assert.NoError(t, err)
    94  
    95  	retrievedchanConf, err := retrievePersistedChannelConfig(lgr)
    96  	assert.NoError(t, err)
    97  	assert.Equal(t, proto.CompactTextString(chanConf), proto.CompactTextString(retrievedchanConf))
    98  
    99  	helper.mockCreateChain(t, channelID, lgr)
   100  	defer helper.clearMockChains()
   101  
   102  	bs := helper.peer.channels[channelID].bundleSource
   103  	inMemoryChanConf := bs.ConfigtxValidator().ConfigProto()
   104  	assert.Equal(t, proto.CompactTextString(chanConf), proto.CompactTextString(inMemoryChanConf))
   105  
   106  	retrievedchanConf, err = retrievePersistedChannelConfig(lgr)
   107  	assert.NoError(t, err)
   108  	assert.Equal(t, proto.CompactTextString(bs.ConfigtxValidator().ConfigProto()), proto.CompactTextString(retrievedchanConf))
   109  
   110  	lgr.Close()
   111  	helper.clearMockChains()
   112  	_, err = ledgerMgr.OpenLedger(channelID)
   113  	assert.NoError(t, err)
   114  }
   115  
   116  func TestGenesisBlockCreateLedger(t *testing.T) {
   117  	b, err := configtxtest.MakeGenesisBlock("testchain")
   118  	assert.NoError(t, err)
   119  	tempdir, err := ioutil.TempDir("", "peer-test")
   120  	require.NoError(t, err, "failed to create temporary directory")
   121  
   122  	ledgerMgr, err := constructLedgerMgrWithTestDefaults(tempdir)
   123  	if err != nil {
   124  		t.Fatalf("Failed to create test environment: %s", err)
   125  	}
   126  
   127  	defer func() {
   128  		ledgerMgr.Close()
   129  		os.RemoveAll(tempdir)
   130  	}()
   131  
   132  	lgr, err := ledgerMgr.CreateLedger("testchain", b)
   133  	assert.NoError(t, err)
   134  	chanConf, err := retrievePersistedChannelConfig(lgr)
   135  	assert.NoError(t, err)
   136  	assert.NotNil(t, chanConf)
   137  	t.Logf("chanConf = %s", chanConf)
   138  }
   139  
   140  type testHelper struct {
   141  	t    *testing.T
   142  	peer *Peer
   143  }
   144  
   145  func newTestHelper(t *testing.T) *testHelper {
   146  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   147  	assert.NoError(t, err)
   148  	return &testHelper{
   149  		t:    t,
   150  		peer: &Peer{CryptoProvider: cryptoProvider},
   151  	}
   152  }
   153  
   154  func (h *testHelper) sampleChannelConfig(sequence uint64, enableV11Capability bool) *common.Config {
   155  	profile := genesisconfig.Load(genesisconfig.SampleDevModeSoloProfile, configtest.GetDevConfigDir())
   156  	if enableV11Capability {
   157  		profile.Orderer.Capabilities = make(map[string]bool)
   158  		profile.Orderer.Capabilities[capabilities.ApplicationV1_1] = true
   159  		profile.Application.Capabilities = make(map[string]bool)
   160  		profile.Application.Capabilities[capabilities.ApplicationV1_2] = true
   161  	}
   162  	channelGroup, _ := encoder.NewChannelGroup(profile)
   163  	return &common.Config{
   164  		Sequence:     sequence,
   165  		ChannelGroup: channelGroup,
   166  	}
   167  }
   168  
   169  func (h *testHelper) constructGenesisTx(t *testing.T, channelID string, chanConf *common.Config) *common.Envelope {
   170  	configEnvelop := &common.ConfigEnvelope{
   171  		Config:     chanConf,
   172  		LastUpdate: h.constructLastUpdateField(channelID),
   173  	}
   174  	txEnvelope, err := protoutil.CreateSignedEnvelope(common.HeaderType_CONFIG, channelID, nil, configEnvelop, 0, 0)
   175  	assert.NoError(t, err)
   176  	return txEnvelope
   177  }
   178  
   179  func (h *testHelper) constructBlock(txEnvelope *common.Envelope, blockNum uint64, previousHash []byte) *common.Block {
   180  	return testutil.NewBlock([]*common.Envelope{txEnvelope}, blockNum, previousHash)
   181  }
   182  
   183  func (h *testHelper) constructLastUpdateField(channelID string) *common.Envelope {
   184  	configUpdate := protoutil.MarshalOrPanic(&common.ConfigUpdate{
   185  		ChannelId: channelID,
   186  	})
   187  	envelopeForLastUpdateField, _ := protoutil.CreateSignedEnvelope(
   188  		common.HeaderType_CONFIG_UPDATE,
   189  		channelID,
   190  		nil,
   191  		&common.ConfigUpdateEnvelope{ConfigUpdate: configUpdate},
   192  		0,
   193  		0,
   194  	)
   195  	return envelopeForLastUpdateField
   196  }
   197  
   198  func (h *testHelper) mockCreateChain(t *testing.T, channelID string, ledger ledger.PeerLedger) {
   199  	chanBundle, err := h.constructChannelBundle(channelID, ledger)
   200  	assert.NoError(t, err)
   201  	if h.peer.channels == nil {
   202  		h.peer.channels = map[string]*Channel{}
   203  	}
   204  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   205  	assert.NoError(t, err)
   206  	h.peer.channels[channelID] = &Channel{
   207  		bundleSource:   channelconfig.NewBundleSource(chanBundle),
   208  		ledger:         ledger,
   209  		cryptoProvider: cryptoProvider,
   210  	}
   211  }
   212  
   213  func (h *testHelper) clearMockChains() {
   214  	h.peer.channels = make(map[string]*Channel)
   215  }
   216  
   217  func (h *testHelper) constructChannelBundle(channelID string, ledger ledger.PeerLedger) (*channelconfig.Bundle, error) {
   218  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   219  	if err != nil {
   220  		return nil, err
   221  	}
   222  
   223  	chanConf, err := retrievePersistedChannelConfig(ledger)
   224  	if err != nil {
   225  		return nil, err
   226  	}
   227  
   228  	return channelconfig.NewBundle(channelID, chanConf, cryptoProvider)
   229  }