Skip to content

Commit 5ca811d

Browse files
author
Jason Yellick
committed
[FAB-4330] Orderer panic on restart
On restart, the orderer is failing to properly re-initialize the config sequence number, which causes it to inappropriately flag new non-config blocks as config blocks. On second restart, the incorrect last config index causes the orderer to attempt to treat a normal transaction as a config transaction. The error checking recognizes this as a fatal error and panics. This CR moves the initialization out of the "new channel" path, and into the common path shared by both startup and restart. It also enhances the log messages to make detection of this sort of scenario easier. Change-Id: I0d730eb5180f21ee6913bc8633ff540128bc6899 Signed-off-by: Jason Yellick <[email protected]>
1 parent 7717a2e commit 5ca811d

File tree

3 files changed

+23
-6
lines changed

3 files changed

+23
-6
lines changed

orderer/multichain/chainsupport.go

+14-1
Original file line numberDiff line numberDiff line change
@@ -122,16 +122,28 @@ func newChainSupport(
122122
signer: signer,
123123
}
124124

125+
cs.lastConfigSeq = cs.Sequence()
126+
125127
var err error
126128

127129
lastBlock := ledger.GetBlock(cs.Reader(), cs.Reader().Height()-1)
130+
131+
// If this is the genesis block, the lastconfig field may be empty, and, the last config is necessary 0
132+
// so no need to initialize lastConfig
133+
if lastBlock.Header.Number != 0 {
134+
cs.lastConfig, err = utils.GetLastConfigIndexFromBlock(lastBlock)
135+
if err != nil {
136+
logger.Fatalf("[channel: %s] Error extracting last config block from block metadata: %s", cs.ChainID(), err)
137+
}
138+
}
139+
128140
metadata, err := utils.GetMetadataFromBlock(lastBlock, cb.BlockMetadataIndex_ORDERER)
129141
// Assuming a block created with cb.NewBlock(), this should not
130142
// error even if the orderer metadata is an empty byte slice
131143
if err != nil {
132144
logger.Fatalf("[channel: %s] Error extracting orderer metadata: %s", cs.ChainID(), err)
133145
}
134-
logger.Debugf("[channel: %s] Retrieved metadata for tip of chain (block #%d): %+v", cs.ChainID(), cs.Reader().Height()-1, metadata)
146+
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)
135147

136148
cs.chain, err = consenter.HandleChain(cs, metadata)
137149
if err != nil {
@@ -222,6 +234,7 @@ func (cs *chainSupport) addBlockSignature(block *cb.Block) {
222234
func (cs *chainSupport) addLastConfigSignature(block *cb.Block) {
223235
configSeq := cs.Sequence()
224236
if configSeq > cs.lastConfigSeq {
237+
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)
225238
cs.lastConfig = block.Header.Number
226239
cs.lastConfigSeq = configSeq
227240
}

orderer/multichain/manager.go

-5
Original file line numberDiff line numberDiff line change
@@ -187,11 +187,6 @@ func (ml *multiLedger) newChain(configtx *cb.Envelope) {
187187

188188
logger.Infof("Created and starting new chain %s", chainID)
189189

190-
cs.lastConfigSeq = cs.Sequence()
191-
// The sequence number on the genesis block of the system channel will be 0.
192-
// The sequence number on the genesis block of every non-system channel will be 1.
193-
logger.Debugf("[channel: %s] Last config set to %d", chainID, cs.lastConfigSeq)
194-
195190
newChains[string(chainID)] = cs
196191
cs.start()
197192

orderer/multichain/manager_test.go

+9
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,15 @@ func TestNewChain(t *testing.T) {
471471
case <-time.After(time.Second):
472472
t.Fatalf("Block 1 not produced after timeout on new chain")
473473
}
474+
475+
testRestartedChainSupport(t, chainSupport, consenters, expectedLastConfigSeq)
476+
}
477+
478+
func testRestartedChainSupport(t *testing.T, cs ChainSupport, consenters map[string]Consenter, expectedLastConfigSeq uint64) {
479+
ccs, ok := cs.(*chainSupport)
480+
assert.True(t, ok, "Casting error")
481+
rcs := newChainSupport(ccs.filters, ccs.ledgerResources, consenters, mockCrypto())
482+
assert.Equal(t, expectedLastConfigSeq, rcs.lastConfigSeq, "On restart, incorrect lastConfigSeq")
474483
}
475484

476485
func testLastConfigBlockNumber(t *testing.T, block *cb.Block, expectedBlockNumber uint64) {

0 commit comments

Comments
 (0)