github.com/lzy4123/fabric@v2.1.1+incompatible/orderer/sample_clients/broadcast_msg/client.go (about)

     1  // Copyright IBM Corp. All Rights Reserved.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package main
     5  
     6  import (
     7  	"context"
     8  	"flag"
     9  	"fmt"
    10  	"os"
    11  	"sync"
    12  
    13  	cb "github.com/hyperledger/fabric-protos-go/common"
    14  	ab "github.com/hyperledger/fabric-protos-go/orderer"
    15  	"github.com/hyperledger/fabric/bccsp/factory"
    16  	"github.com/hyperledger/fabric/internal/pkg/identity"
    17  	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
    18  	"github.com/hyperledger/fabric/orderer/common/localconfig"
    19  	"github.com/hyperledger/fabric/protoutil"
    20  	"google.golang.org/grpc"
    21  	pb "gopkg.in/cheggaaa/pb.v1"
    22  )
    23  
    24  type broadcastClient struct {
    25  	client    ab.AtomicBroadcast_BroadcastClient
    26  	signer    identity.SignerSerializer
    27  	channelID string
    28  }
    29  
    30  // newBroadcastClient creates a simple instance of the broadcastClient interface
    31  func newBroadcastClient(client ab.AtomicBroadcast_BroadcastClient, channelID string, signer identity.SignerSerializer) *broadcastClient {
    32  	return &broadcastClient{client: client, channelID: channelID, signer: signer}
    33  }
    34  
    35  func (s *broadcastClient) broadcast(transaction []byte) error {
    36  	env, err := protoutil.CreateSignedEnvelope(cb.HeaderType_MESSAGE, s.channelID, s.signer, &cb.ConfigValue{Value: transaction}, 0, 0)
    37  	if err != nil {
    38  		panic(err)
    39  	}
    40  	return s.client.Send(env)
    41  }
    42  
    43  func (s *broadcastClient) getAck() error {
    44  	msg, err := s.client.Recv()
    45  	if err != nil {
    46  		return err
    47  	}
    48  	if msg.Status != cb.Status_SUCCESS {
    49  		return fmt.Errorf("got unexpected status: %v - %s", msg.Status, msg.Info)
    50  	}
    51  	return nil
    52  }
    53  
    54  func main() {
    55  	conf, err := localconfig.Load()
    56  	if err != nil {
    57  		fmt.Println("failed to load config:", err)
    58  		os.Exit(1)
    59  	}
    60  
    61  	// Load local MSP
    62  	err = mspmgmt.LoadLocalMsp(conf.General.LocalMSPDir, conf.General.BCCSP, conf.General.LocalMSPID)
    63  	if err != nil { // Handle errors reading the config file
    64  		fmt.Println("Failed to initialize local MSP:", err)
    65  		os.Exit(0)
    66  	}
    67  
    68  	signer, err := mspmgmt.GetLocalMSP(factory.GetDefault()).GetDefaultSigningIdentity()
    69  	if err != nil {
    70  		fmt.Println("Failed to load local signing identity:", err)
    71  		os.Exit(0)
    72  	}
    73  
    74  	var channelID string
    75  	var serverAddr string
    76  	var messages uint64
    77  	var goroutines uint64
    78  	var msgSize uint64
    79  	var bar *pb.ProgressBar
    80  
    81  	flag.StringVar(&serverAddr, "server", fmt.Sprintf("%s:%d", conf.General.ListenAddress, conf.General.ListenPort), "The RPC server to connect to.")
    82  	flag.StringVar(&channelID, "channelID", "mychannel", "The channel ID to broadcast to.")
    83  	flag.Uint64Var(&messages, "messages", 1, "The number of messages to broadcast.")
    84  	flag.Uint64Var(&goroutines, "goroutines", 1, "The number of concurrent go routines to broadcast the messages on")
    85  	flag.Uint64Var(&msgSize, "size", 1024, "The size in bytes of the data section for the payload")
    86  	flag.Parse()
    87  
    88  	conn, err := grpc.Dial(serverAddr, grpc.WithInsecure())
    89  	defer func() {
    90  		_ = conn.Close()
    91  	}()
    92  	if err != nil {
    93  		fmt.Println("Error connecting:", err)
    94  		return
    95  	}
    96  
    97  	msgsPerGo := messages / goroutines
    98  	roundMsgs := msgsPerGo * goroutines
    99  	if roundMsgs != messages {
   100  		fmt.Println("Rounding messages to", roundMsgs)
   101  	}
   102  	bar = pb.New64(int64(roundMsgs))
   103  	bar.ShowPercent = true
   104  	bar.ShowSpeed = true
   105  	bar = bar.Start()
   106  
   107  	msgData := make([]byte, msgSize)
   108  
   109  	var wg sync.WaitGroup
   110  	wg.Add(int(goroutines))
   111  	for i := uint64(0); i < goroutines; i++ {
   112  		go func(i uint64, pb *pb.ProgressBar) {
   113  			client, err := ab.NewAtomicBroadcastClient(conn).Broadcast(context.TODO())
   114  			if err != nil {
   115  				fmt.Println("Error connecting:", err)
   116  				return
   117  			}
   118  
   119  			s := newBroadcastClient(client, channelID, signer)
   120  			done := make(chan (struct{}))
   121  			go func() {
   122  				for i := uint64(0); i < msgsPerGo; i++ {
   123  					err = s.getAck()
   124  					if err == nil && bar != nil {
   125  						bar.Increment()
   126  					}
   127  				}
   128  				if err != nil {
   129  					fmt.Printf("\nError: %v\n", err)
   130  				}
   131  				close(done)
   132  			}()
   133  			for i := uint64(0); i < msgsPerGo; i++ {
   134  				if err := s.broadcast(msgData); err != nil {
   135  					panic(err)
   136  				}
   137  			}
   138  			<-done
   139  			wg.Done()
   140  			client.CloseSend()
   141  		}(i, bar)
   142  	}
   143  
   144  	wg.Wait()
   145  	bar.FinishPrint("----------------------broadcast message finish-------------------------------")
   146  }