Open 1gezhanghao opened 1 year ago
I think you are mixing two separate concerns. The GetConfigBlockFromOrderer
function is needed to get the current config block in order to update the channel configuration. This function is helpful because you don't necessarily know the latest configuration block number, and this function both finds the latest configuration block number and then obtains the block for you.
The genesis block is just block zero. You don't need any special admin function to get a specific block by its number. To get block zero, you can either:
GetBlockByNumber
transaction function on the qscc system chaincode.Perhaps you could argue that it is convenient for the admin API to provide a GetGenesisBlock
function but I am not convinced that it is worth increasing the size of the admin API for something that is already easily achieved using the existing client application APIs. The exception to this is for the situation where you need to join peers to channels that contain no peers. The client APIs talk to peers, whereas you would need to obtain to genesis block from an orderer, which the admin API could do with a GetGenesisBlock
function. If you are in this situation then perhaps you are the creator of the network anyway, in which case you should already have the genesis block you used to create that network with no peers.
@bestbeforetoday
I'll explain step by step more clearly,
1 orderer cluster create a channel, there is no org info on the configblock now.
2 org A join the channel:
GetConfigBlockFromOrderer
(now the block number is 0 ,so this is the GenesisBlock)3 org B join the channel:
GetConfigBlockFromOrderer
(now the configblock number is 1, can't get the GenesisBlock now)For org B, there is no way to get the GenesisBlock from it's peer before it joined in except use an api from orderer. i don't think save the GenesisBlock on local disk by user is a goog idea once the channel be created
and JoinChannel
on the old fabric-sdk-go is designed without blockinfo, it is more simple.
func (rc *Client) JoinChannel(channelID string, options ...RequestOption) error {
so, maybe ChannelJoin API can be designed more simpler without blockinfo or give a GetGenesisBlock
can solve the problem
maybe GetConfigBlockFromOrderer
give two block is a good way the LatestBlock & the GenesisBlock.
I extended a funtion GetGenesisBlockFromOrderer
myself,this issue is closed for me.
func GetGenesisBlockFromOrderer(ctx context.Context, connection grpc.ClientConnInterface, id identity.SigningIdentity, channelID string, certificate tls.Certificate) (*cb.Block, error) {
abClient := ab.NewAtomicBroadcastClient(connection)
deliverClient, err := abClient.Deliver(ctx)
if err != nil {
return nil, err
}
return getSpecifiedBlock(deliverClient, channelID, certificate, id, true, 0)
}
I agree, if the channel join API can be simplified so the caller does not need to supply genesis and/or config blocks themselves, that might be the neatest solution.
For an exist channel , when a new org need to be added to channel: the channel's configBlock is updated first, then the org's peers join the channel
code may like as follows
JoinChannel(...) will give an error: unsuccessful response received with status 500 (INTERNAL_SERVER_ERROR): cannot create ledger from genesis block: expected block number=0, received block number=1
So when a peer join the channl it will always need the number 0 ConfigBlock, is it correct? but channel.GetConfigBlockFromOrderer(...) always return the latest ConfigBlock so we need a func like channel.GetConfigBlockFromOrdererByNumber(0) or channel.GetFirstConfigBlockFromOrderer() to get the first ConfigBlock to support peer join