Not able receive block level events in hyperledger fabric golang

27 views Asked by At

I was trying to listen block level events in Golang. I am not able to receive blocklevel events at all. It is just showing block 0 always and not moving ahead. I have given the sample code. Please let me know if there is any problem with the code or any other setting to be performed at network level. One more observation is if the code is written in nodejs than I am able to listen block level event but not in Golang.

Please let me know if any solution is available. We are using hyperledgr fabric 2.4

func startBlocklevelEventListening(ctx context.Context, network client.Network) {
blockEvents, blockErr := network.BlockEvents(ctx, client.WithStartBlock(1))
if blockErr != nil {
panic(fmt.Errorf("failed to start chaincode event listening: %w", blockErr))
}
fmt.Println("\n** Start Block event listening")

go func() {
    for event := range blockEvents {
        hashBytes := event.GetHeader().GetDataHash()
        hashString := fmt.Sprintf("%x", hashBytes)
        blockNumber := event.GetHeader().GetNumber()
        fmt.Printf("\n<-- Block event received: \n   Received block number : %d \n   Received block hash - %s\n", blockNumber, hashString)
    }
}()
1

There are 1 answers

0
bestbeforetoday On

I tried this out using Fabric v2.5 and fabric-gateway v1.4, and I am able to receive block events. I made the following modifications to the existing asset-transfer-events/application-gateway-go sample:

  1. Modified the deleteAsset function so that it returned the block number in which the transaction is committed (similar to the existing createAsset function).

    func deleteAsset(contract *client.Contract) uint64 {
        fmt.Printf("\n--> Submit transaction: DeleteAsset, %s\n", assetID)
    
        _, commit, err := contract.SubmitAsync("DeleteAsset", client.WithArguments(assetID))
        if err != nil {
            panic(fmt.Errorf("failed to submit transaction: %w", err))
        }
    
        status, err := commit.Status()
        if err != nil {
            panic(fmt.Errorf("failed to get transaction commit status: %w", err))
        }
    
        if !status.Successful {
            panic(fmt.Errorf("failed to commit transaction with status code %v", status.Code))
        }
    
        fmt.Println("\n*** DeleteAsset committed successfully")
    
        return status.BlockNumber
    }
    
  2. Added a replayBlockEvents function, similar to the existing replayChaincodeEvents function.

    func replayBlockEvents(ctx context.Context, network *client.Network, endBlock uint64) {
        fmt.Println("\n*** Start block event replay")
    
        events, err := network.BlockEvents(ctx, client.WithStartBlock(0))
        if err != nil {
            panic(fmt.Errorf("failed to start block event listening: %w", err))
        }
    
        for {
            select {
            case <-time.After(10 * time.Second):
                panic(errors.New("timeout waiting for event replay"))
    
            case event := <-events:
                blockNumber := event.GetHeader().GetNumber()
                fmt.Printf("\n<-- Replayed block number %d\n", blockNumber)
    
                if blockNumber == endBlock {
                    // Reached the block containing the last submitted transaction so return to stop listening for events
                    return
                }
            }
        }
    }
    
  3. Modified the last part of the main function to add replay of block events.

    firstBlockNumber := createAsset(contract)
    updateAsset(contract)
    transferAsset(contract)
    lastBlockNumber := deleteAsset(contract)
    
    // Replay chaincode events from the block containing the first transaction
    replayChaincodeEvents(ctx, network, firstBlockNumber)
    // Replay block events up to the last committed block
    replayBlockEvents(ctx, network, lastBlockNumber)
    

Running this application produced the usual console output, plus this additional output from the replayBlockEvents function, clearly indicating that block eventing is working:

*** Start block event replay
<-- Replayed block number 0
<-- Replayed block number 1
<-- Replayed block number 2
<-- Replayed block number 3
<-- Replayed block number 4
<-- Replayed block number 5
<-- Replayed block number 6
<-- Replayed block number 7
<-- Replayed block number 8
<-- Replayed block number 9

Using a simpler for-range loop in the replayBlockEvents function also worked.

for event := range events {
    blockNumber := event.GetHeader().GetNumber()
    fmt.Printf("\n<-- Replayed block number %d\n", blockNumber)

    if blockNumber == endBlock {
        // Reached the block containing the last submitted transaction so return to stop listening for events
        return
    }
}