diff --git a/orderer/common/server/main.go b/orderer/common/server/main.go index 7baf0c1c63a..ac2d0a8c499 100644 --- a/orderer/common/server/main.go +++ b/orderer/common/server/main.go @@ -384,31 +384,6 @@ func reuseListener(conf *localconfig.TopLevel) bool { return false } -// Extract system channel last config block -func extractSysChanLastConfig(lf blockledger.Factory, bootstrapBlock *cb.Block) *cb.Block { - // Are we bootstrapping? - channelCount := len(lf.ChannelIDs()) - if channelCount == 0 { - logger.Info("Bootstrapping because no existing channels") - return nil - } - logger.Infof("Not bootstrapping because of %d existing channels", channelCount) - - systemChannelName, err := protoutil.GetChannelIDFromBlock(bootstrapBlock) - if err != nil { - logger.Panicf("Failed extracting system channel name from bootstrap block: %v", err) - } - systemChannelLedger, err := lf.GetOrCreate(systemChannelName) - if err != nil { - logger.Panicf("Failed getting system channel ledger: %v", err) - } - height := systemChannelLedger.Height() - lastConfigBlock := multichannel.ConfigBlockOrPanic(systemChannelLedger) - logger.Infof("System channel: name=%s, height=%d, last config block number=%d", - systemChannelName, height, lastConfigBlock.Header.Number) - return lastConfigBlock -} - // extractSystemChannel loops through all channels, and return the last // config block for the system channel. Returns nil if no system channel // was found. @@ -418,6 +393,10 @@ func extractSystemChannel(lf blockledger.Factory, bccsp bccsp.BCCSP) *cb.Block { if err != nil { logger.Panicf("Failed getting channel %v's ledger: %v", cID, err) } + if channelLedger.Height() == 0 { + continue // Some channels may have an empty ledger and (possibly) a join-block, skip those + } + channelConfigBlock := multichannel.ConfigBlockOrPanic(channelLedger) err = onboarding.ValidateBootstrapBlock(channelConfigBlock, bccsp) diff --git a/orderer/common/server/main_test.go b/orderer/common/server/main_test.go index 7bdfb867247..a68c1c3bfff 100644 --- a/orderer/common/server/main_test.go +++ b/orderer/common/server/main_test.go @@ -394,7 +394,9 @@ func TestInitSystemChannelWithJoinBlock(t *testing.T) { } -func TestExtractSysChanLastConfig(t *testing.T) { +func TestExtractSystemChannel(t *testing.T) { + cryptoProvider, _ := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) + tmpdir, err := ioutil.TempDir("", "main_test-") require.NoError(t, err) defer os.RemoveAll(tmpdir) @@ -402,43 +404,52 @@ func TestExtractSysChanLastConfig(t *testing.T) { rlf, err := fileledger.New(tmpdir, &disabled.Provider{}) require.NoError(t, err) - conf := genesisconfig.Load(genesisconfig.SampleInsecureSoloProfile, configtest.GetDevConfigDir()) - genesisBlock := encoder.New(conf).GenesisBlock() - - lastConf := extractSysChanLastConfig(rlf, genesisBlock) - require.Nil(t, lastConf) + lastConf := extractSystemChannel(rlf, cryptoProvider) + require.Nil(t, lastConf, "no ledgers") - rl, err := rlf.GetOrCreate("testchannelid") + _, err = rlf.GetOrCreate("emptychannelid") require.NoError(t, err) - err = rl.Append(genesisBlock) - require.NoError(t, err) + lastConf = extractSystemChannel(rlf, cryptoProvider) + require.Nil(t, lastConf, "skip empty ledger") - lastConf = extractSysChanLastConfig(rlf, genesisBlock) - require.NotNil(t, lastConf) - require.Equal(t, uint64(0), lastConf.Header.Number) + conf := genesisconfig.Load(genesisconfig.SampleInsecureSoloProfile, configtest.GetDevConfigDir()) + conf.Consortiums = nil + configBlock := encoder.New(conf).GenesisBlock() + rl, err := rlf.GetOrCreate("appchannelid") + err = rl.Append(configBlock) + require.NoError(t, err) - require.Panics(t, func() { - _ = extractSysChanLastConfig(rlf, nil) - }) + lastConf = extractSystemChannel(rlf, cryptoProvider) + require.Nil(t, lastConf, "skip app ledger") - configTx, err := protoutil.CreateSignedEnvelope(common.HeaderType_CONFIG, "testchannelid", nil, &common.ConfigEnvelope{}, 0, 0) + conf = genesisconfig.Load(genesisconfig.SampleInsecureSoloProfile, configtest.GetDevConfigDir()) + configBlock = encoder.New(conf).GenesisBlock() + rl, err = rlf.GetOrCreate("testchannelid") + err = rl.Append(configBlock) require.NoError(t, err) - nextBlock := blockledger.CreateNextBlock(rl, []*common.Envelope{configTx}) - nextBlock.Metadata.Metadata[common.BlockMetadataIndex_SIGNATURES] = protoutil.MarshalOrPanic(&common.Metadata{ + lastConf = extractSystemChannel(rlf, cryptoProvider) + require.NotNil(t, lastConf, "get system channel genesis block") + require.Equal(t, uint64(0), lastConf.Header.Number) + + // Make and append the next config block + prevHash := protoutil.BlockHeaderHash(configBlock.Header) + configBlock.Header.Number = 1 + configBlock.Header.PreviousHash = prevHash + configBlock.Metadata.Metadata[common.BlockMetadataIndex_SIGNATURES] = protoutil.MarshalOrPanic(&common.Metadata{ Value: protoutil.MarshalOrPanic(&common.OrdererBlockMetadata{ LastConfig: &common.LastConfig{Index: rl.Height()}, }), }) - nextBlock.Metadata.Metadata[common.BlockMetadataIndex_LAST_CONFIG] = protoutil.MarshalOrPanic(&common.Metadata{ + configBlock.Metadata.Metadata[common.BlockMetadataIndex_LAST_CONFIG] = protoutil.MarshalOrPanic(&common.Metadata{ Value: protoutil.MarshalOrPanic(&common.LastConfig{Index: rl.Height()}), }) - err = rl.Append(nextBlock) + err = rl.Append(configBlock) require.NoError(t, err) - lastConf = extractSysChanLastConfig(rlf, genesisBlock) - require.NotNil(t, lastConf) + lastConf = extractSystemChannel(rlf, cryptoProvider) + require.NotNil(t, lastConf, "get system channel last config block") require.Equal(t, uint64(1), lastConf.Header.Number) }