diff --git a/orderer/multichain/chainsupport.go b/orderer/multichain/chainsupport.go index 9dce611771a..10cfbce81dd 100644 --- a/orderer/multichain/chainsupport.go +++ b/orderer/multichain/chainsupport.go @@ -122,16 +122,28 @@ func newChainSupport( signer: signer, } + cs.lastConfigSeq = cs.Sequence() + var err error lastBlock := ledger.GetBlock(cs.Reader(), cs.Reader().Height()-1) + + // If this is the genesis block, the lastconfig field may be empty, and, the last config is necessary 0 + // so no need to initialize lastConfig + if lastBlock.Header.Number != 0 { + cs.lastConfig, err = utils.GetLastConfigIndexFromBlock(lastBlock) + if err != nil { + logger.Fatalf("[channel: %s] Error extracting last config block from block metadata: %s", cs.ChainID(), err) + } + } + metadata, err := utils.GetMetadataFromBlock(lastBlock, cb.BlockMetadataIndex_ORDERER) // Assuming a block created with cb.NewBlock(), this should not // error even if the orderer metadata is an empty byte slice if err != nil { logger.Fatalf("[channel: %s] Error extracting orderer metadata: %s", cs.ChainID(), err) } - logger.Debugf("[channel: %s] Retrieved metadata for tip of chain (block #%d): %+v", cs.ChainID(), cs.Reader().Height()-1, metadata) + logger.Debugf("[channel: %s] Retrieved metadata for tip of chain (blockNumber=%d, lastConfig=%d, lastConfigSeq=%d): %+v", cs.ChainID(), lastBlock.Header.Number, cs.lastConfig, cs.lastConfigSeq, metadata) cs.chain, err = consenter.HandleChain(cs, metadata) if err != nil { @@ -222,6 +234,7 @@ func (cs *chainSupport) addBlockSignature(block *cb.Block) { func (cs *chainSupport) addLastConfigSignature(block *cb.Block) { configSeq := cs.Sequence() if configSeq > cs.lastConfigSeq { + logger.Debugf("[channel: %s] Detected lastConfigSeq transitioning from %d to %d, setting lastConfig from %d to %d", cs.ChainID(), cs.lastConfigSeq, configSeq, cs.lastConfig, block.Header.Number) cs.lastConfig = block.Header.Number cs.lastConfigSeq = configSeq } diff --git a/orderer/multichain/manager.go b/orderer/multichain/manager.go index 06334140a3e..e59a0aa8927 100644 --- a/orderer/multichain/manager.go +++ b/orderer/multichain/manager.go @@ -187,11 +187,6 @@ func (ml *multiLedger) newChain(configtx *cb.Envelope) { logger.Infof("Created and starting new chain %s", chainID) - cs.lastConfigSeq = cs.Sequence() - // The sequence number on the genesis block of the system channel will be 0. - // The sequence number on the genesis block of every non-system channel will be 1. - logger.Debugf("[channel: %s] Last config set to %d", chainID, cs.lastConfigSeq) - newChains[string(chainID)] = cs cs.start() diff --git a/orderer/multichain/manager_test.go b/orderer/multichain/manager_test.go index e8517d4d6a6..edd070382c2 100644 --- a/orderer/multichain/manager_test.go +++ b/orderer/multichain/manager_test.go @@ -471,6 +471,15 @@ func TestNewChain(t *testing.T) { case <-time.After(time.Second): t.Fatalf("Block 1 not produced after timeout on new chain") } + + testRestartedChainSupport(t, chainSupport, consenters, expectedLastConfigSeq) +} + +func testRestartedChainSupport(t *testing.T, cs ChainSupport, consenters map[string]Consenter, expectedLastConfigSeq uint64) { + ccs, ok := cs.(*chainSupport) + assert.True(t, ok, "Casting error") + rcs := newChainSupport(ccs.filters, ccs.ledgerResources, consenters, mockCrypto()) + assert.Equal(t, expectedLastConfigSeq, rcs.lastConfigSeq, "On restart, incorrect lastConfigSeq") } func testLastConfigBlockNumber(t *testing.T, block *cb.Block, expectedBlockNumber uint64) {