Fabric中chain code支持升级,用name+version来标识一个chain code,在调用一个chain code时可以指定version,但是endorser只会调用目标channel中chaincode的最新版本。在endorser接到请求是他会调用LSCC获取执行chain code的信息,当一个chain code升级后,LSCC就会更新该chaincode信息。
那么一个问题就是如果一个chaincode已经升级,但是有个别节点还未获得包含升级信息的区块,这个时候如果请求到该节点会如何?实际上,在执行chaincode时,因为该节点未获得升级信息,所以他还会用当前版本升级,但在返回propose response中会包含执行chain code的版本信息。Client在收集足够的response后,发送transaction到orderer service,orderer service会将该transaction打包到一个区块中。因为升级发生在chaincode调用之前,tx的区块肯定在升级区块之后。则Peer先收到升级区块,后收到包含tx的区块,在验证tx时就会发现chaincode已经升级了,所以就会标记该chaincode未非法(EXPIRED_CHAINCODE)
参考:
https://github.com/hyperledger/fabric/blob/release-1.1/protos/peer/chaincode.proto
https://github.com/hyperledger/fabric/blob/release-1.1/core/endorser/endorser.go
https://github.com/hyperledger/fabric/blob/release-1.1/core/committer/txvalidator/validator.go