github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/orderer/sample_clients/broadcast_msg/client.go (about)

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