Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

to support GetConfigBlockFromOrdererByNumber #124

Open
1gezhanghao opened this issue May 19, 2023 · 4 comments
Open

to support GetConfigBlockFromOrdererByNumber #124

1gezhanghao opened this issue May 19, 2023 · 4 comments

Comments

@1gezhanghao
Copy link
Contributor

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

//code update the configblock
...
...

//code to get the latest configblock
block, err = channel.GetConfigBlockFromOrderer(context.Background(), orderer0.Conn, orderer0.Signer, channelID, orderer0.KeyPair)                                                                                                         
if err != nil {                                                                                                                                                                                                                           
        logger.Error(err)                                                                                                                                                                                                                 
        return err                                                                                                                                                                                                                        
}  
//code to make peer join the channel
err := channel.JoinChannel(block, peerCli.Signer, peer.NewEndorserClient(peerCli.Conn))                                                                                                                                           
if err != nil {                                                                                                                                                                                                                   
        logger.Error(err)                                                                                                                                                                                                                 
        return err                                                                                                                                                                                              
}                                                                                                                                                                                                                                 

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

@bestbeforetoday
Copy link
Member

bestbeforetoday commented May 19, 2023

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:

  1. Use block eventing to get block events from block zero and stop as soon as you receive that initial block; or
  2. Evaluate the 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.

@1gezhanghao
Copy link
Contributor Author

1gezhanghao commented May 22, 2023

@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)
  • update the channel with org A info (now the latest config block is number 1)
  • join the channel with the number 0 block will succeed

3 org B join the channel:

  • GetConfigBlockFromOrderer (now the configblock number is 1, can't get the GenesisBlock now)
  • update the channel with org B info (now the latest config block number is added)
  • join the channel with number ? block(no way to get the number 0 configblock, always fail)

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.

@1gezhanghao
Copy link
Contributor Author

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)                                                                                                                                                                       
}    

@bestbeforetoday
Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants