go_study/fabric-main/core/peer/configtx_test.go

221 lines
7.1 KiB
Go

/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package peer
import (
"testing"
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric-protos-go/common"
"github.com/hyperledger/fabric/bccsp/sw"
"github.com/hyperledger/fabric/common/capabilities"
"github.com/hyperledger/fabric/common/channelconfig"
configtxtest "github.com/hyperledger/fabric/common/configtx/test"
"github.com/hyperledger/fabric/common/ledger/testutil"
"github.com/hyperledger/fabric/core/config/configtest"
"github.com/hyperledger/fabric/core/ledger"
"github.com/hyperledger/fabric/internal/configtxgen/encoder"
"github.com/hyperledger/fabric/internal/configtxgen/genesisconfig"
"github.com/hyperledger/fabric/protoutil"
"github.com/stretchr/testify/require"
)
func TestConfigTxCreateLedger(t *testing.T) {
helper := newTestHelper(t)
channelID := "testchain1"
tempdir := t.TempDir()
ledgerMgr, err := constructLedgerMgrWithTestDefaults(tempdir)
if err != nil {
t.Fatalf("Failed to create test environment: %s", err)
}
defer func() {
ledgerMgr.Close()
}()
chanConf := helper.sampleChannelConfig(1, true)
genesisTx := helper.constructGenesisTx(t, channelID, chanConf)
genesisBlock := helper.constructBlock(genesisTx, 0, nil)
ledger, err := ledgerMgr.CreateLedger(channelID, genesisBlock)
require.NoError(t, err)
retrievedchanConf, err := RetrievePersistedChannelConfig(ledger)
require.NoError(t, err)
require.Equal(t, proto.CompactTextString(chanConf), proto.CompactTextString(retrievedchanConf))
}
func TestConfigTxErrorScenarios(t *testing.T) {
configTxProcessor := &ConfigTxProcessor{}
// wrong tx type
configEnvWrongTxType := &common.ConfigEnvelope{}
txEnvelope, err := protoutil.CreateSignedEnvelope(common.HeaderType_DELIVER_SEEK_INFO, "channelID", nil, configEnvWrongTxType, 0, 0)
require.NoError(t, err)
err = configTxProcessor.GenerateSimulationResults(txEnvelope, nil, false)
require.EqualError(t, err, "tx type [DELIVER_SEEK_INFO] is not expected")
// empty channelConfig
txEnvelope, err = protoutil.CreateSignedEnvelope(common.HeaderType_CONFIG, "channelID", nil, &common.ConfigEnvelope{}, 0, 0)
require.NoError(t, err)
err = configTxProcessor.GenerateSimulationResults(txEnvelope, nil, false)
require.EqualError(t, err, "channel config found nil")
}
func TestConfigTxUpdateChanConfig(t *testing.T) {
helper := newTestHelper(t)
channelID := "testchain1"
tempdir := t.TempDir()
ledgerMgr, err := constructLedgerMgrWithTestDefaults(tempdir)
if err != nil {
t.Fatalf("Failed to create test environment: %s", err)
}
defer func() {
ledgerMgr.Close()
}()
chanConf := helper.sampleChannelConfig(1, true)
genesisTx := helper.constructGenesisTx(t, channelID, chanConf)
genesisBlock := helper.constructBlock(genesisTx, 0, nil)
lgr, err := ledgerMgr.CreateLedger(channelID, genesisBlock)
require.NoError(t, err)
retrievedchanConf, err := RetrievePersistedChannelConfig(lgr)
require.NoError(t, err)
require.Equal(t, proto.CompactTextString(chanConf), proto.CompactTextString(retrievedchanConf))
helper.mockCreateChain(t, channelID, lgr)
defer helper.clearMockChains()
bs := helper.peer.channels[channelID].bundleSource
inMemoryChanConf := bs.ConfigtxValidator().ConfigProto()
require.Equal(t, proto.CompactTextString(chanConf), proto.CompactTextString(inMemoryChanConf))
retrievedchanConf, err = RetrievePersistedChannelConfig(lgr)
require.NoError(t, err)
require.Equal(t, proto.CompactTextString(bs.ConfigtxValidator().ConfigProto()), proto.CompactTextString(retrievedchanConf))
lgr.Close()
helper.clearMockChains()
_, err = ledgerMgr.OpenLedger(channelID)
require.NoError(t, err)
}
func TestGenesisBlockCreateLedger(t *testing.T) {
b, err := configtxtest.MakeGenesisBlock("testchain")
require.NoError(t, err)
tempdir := t.TempDir()
ledgerMgr, err := constructLedgerMgrWithTestDefaults(tempdir)
if err != nil {
t.Fatalf("Failed to create test environment: %s", err)
}
defer func() {
ledgerMgr.Close()
}()
lgr, err := ledgerMgr.CreateLedger("testchain", b)
require.NoError(t, err)
chanConf, err := RetrievePersistedChannelConfig(lgr)
require.NoError(t, err)
require.NotNil(t, chanConf)
t.Logf("chanConf = %s", chanConf)
}
type testHelper struct {
t *testing.T
peer *Peer
}
func newTestHelper(t *testing.T) *testHelper {
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
require.NoError(t, err)
return &testHelper{
t: t,
peer: &Peer{CryptoProvider: cryptoProvider},
}
}
func (h *testHelper) sampleChannelConfig(sequence uint64, enableV11Capability bool) *common.Config {
profile := genesisconfig.Load(genesisconfig.SampleDevModeSoloProfile, configtest.GetDevConfigDir())
if enableV11Capability {
profile.Orderer.Capabilities = make(map[string]bool)
profile.Orderer.Capabilities[capabilities.ApplicationV1_1] = true
profile.Application.Capabilities = make(map[string]bool)
profile.Application.Capabilities[capabilities.ApplicationV1_2] = true
}
channelGroup, _ := encoder.NewChannelGroup(profile)
return &common.Config{
Sequence: sequence,
ChannelGroup: channelGroup,
}
}
func (h *testHelper) constructGenesisTx(t *testing.T, channelID string, chanConf *common.Config) *common.Envelope {
configEnvelop := &common.ConfigEnvelope{
Config: chanConf,
LastUpdate: h.constructLastUpdateField(channelID),
}
txEnvelope, err := protoutil.CreateSignedEnvelope(common.HeaderType_CONFIG, channelID, nil, configEnvelop, 0, 0)
require.NoError(t, err)
return txEnvelope
}
func (h *testHelper) constructBlock(txEnvelope *common.Envelope, blockNum uint64, previousHash []byte) *common.Block {
return testutil.NewBlock([]*common.Envelope{txEnvelope}, blockNum, previousHash)
}
func (h *testHelper) constructLastUpdateField(channelID string) *common.Envelope {
configUpdate := protoutil.MarshalOrPanic(&common.ConfigUpdate{
ChannelId: channelID,
})
envelopeForLastUpdateField, _ := protoutil.CreateSignedEnvelope(
common.HeaderType_CONFIG_UPDATE,
channelID,
nil,
&common.ConfigUpdateEnvelope{ConfigUpdate: configUpdate},
0,
0,
)
return envelopeForLastUpdateField
}
func (h *testHelper) mockCreateChain(t *testing.T, channelID string, ledger ledger.PeerLedger) {
chanBundle, err := h.constructChannelBundle(channelID, ledger)
require.NoError(t, err)
if h.peer.channels == nil {
h.peer.channels = map[string]*Channel{}
}
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
require.NoError(t, err)
h.peer.channels[channelID] = &Channel{
bundleSource: channelconfig.NewBundleSource(chanBundle),
ledger: ledger,
cryptoProvider: cryptoProvider,
}
}
func (h *testHelper) clearMockChains() {
h.peer.channels = make(map[string]*Channel)
}
func (h *testHelper) constructChannelBundle(channelID string, ledger ledger.PeerLedger) (*channelconfig.Bundle, error) {
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
if err != nil {
return nil, err
}
chanConf, err := RetrievePersistedChannelConfig(ledger)
if err != nil {
return nil, err
}
return channelconfig.NewBundle(channelID, chanConf, cryptoProvider)
}