github.com/kaituanwang/hyperledger@v2.0.1+incompatible/orderer/sample_clients/deliver_stdout/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  	"math"
    11  	"os"
    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/common/tools/protolator"
    17  	"github.com/hyperledger/fabric/internal/pkg/identity"
    18  	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
    19  	"github.com/hyperledger/fabric/orderer/common/localconfig"
    20  	"github.com/hyperledger/fabric/protoutil"
    21  	"google.golang.org/grpc"
    22  )
    23  
    24  var (
    25  	oldest  = &ab.SeekPosition{Type: &ab.SeekPosition_Oldest{Oldest: &ab.SeekOldest{}}}
    26  	newest  = &ab.SeekPosition{Type: &ab.SeekPosition_Newest{Newest: &ab.SeekNewest{}}}
    27  	maxStop = &ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: math.MaxUint64}}}
    28  )
    29  
    30  type deliverClient struct {
    31  	client    ab.AtomicBroadcast_DeliverClient
    32  	channelID string
    33  	signer    identity.SignerSerializer
    34  	quiet     bool
    35  }
    36  
    37  func newDeliverClient(client ab.AtomicBroadcast_DeliverClient, channelID string, signer identity.SignerSerializer, quiet bool) *deliverClient {
    38  	return &deliverClient{client: client, channelID: channelID, signer: signer, quiet: quiet}
    39  }
    40  
    41  func (r *deliverClient) seekHelper(start *ab.SeekPosition, stop *ab.SeekPosition) *cb.Envelope {
    42  	env, err := protoutil.CreateSignedEnvelope(cb.HeaderType_DELIVER_SEEK_INFO, r.channelID, r.signer, &ab.SeekInfo{
    43  		Start:    start,
    44  		Stop:     stop,
    45  		Behavior: ab.SeekInfo_BLOCK_UNTIL_READY,
    46  	}, 0, 0)
    47  	if err != nil {
    48  		panic(err)
    49  	}
    50  	return env
    51  }
    52  
    53  func (r *deliverClient) seekOldest() error {
    54  	return r.client.Send(r.seekHelper(oldest, maxStop))
    55  }
    56  
    57  func (r *deliverClient) seekNewest() error {
    58  	return r.client.Send(r.seekHelper(newest, maxStop))
    59  }
    60  
    61  func (r *deliverClient) seekSingle(blockNumber uint64) error {
    62  	specific := &ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: blockNumber}}}
    63  	return r.client.Send(r.seekHelper(specific, specific))
    64  }
    65  
    66  func (r *deliverClient) readUntilClose() {
    67  	for {
    68  		msg, err := r.client.Recv()
    69  		if err != nil {
    70  			fmt.Println("Error receiving:", err)
    71  			return
    72  		}
    73  
    74  		switch t := msg.Type.(type) {
    75  		case *ab.DeliverResponse_Status:
    76  			fmt.Println("Got status ", t)
    77  			return
    78  		case *ab.DeliverResponse_Block:
    79  			if !r.quiet {
    80  				fmt.Println("Received block: ")
    81  				err := protolator.DeepMarshalJSON(os.Stdout, t.Block)
    82  				if err != nil {
    83  					fmt.Printf("  Error pretty printing block: %s", err)
    84  				}
    85  			} else {
    86  				fmt.Println("Received block: ", t.Block.Header.Number)
    87  			}
    88  		}
    89  	}
    90  }
    91  
    92  func main() {
    93  	conf, err := localconfig.Load()
    94  	if err != nil {
    95  		fmt.Println("failed to load config:", err)
    96  		os.Exit(1)
    97  	}
    98  
    99  	// Load local MSP
   100  	err = mspmgmt.LoadLocalMsp(conf.General.LocalMSPDir, conf.General.BCCSP, conf.General.LocalMSPID)
   101  	if err != nil { // Handle errors reading the config file
   102  		fmt.Println("Failed to initialize local MSP:", err)
   103  		os.Exit(0)
   104  	}
   105  
   106  	signer, err := mspmgmt.GetLocalMSP(factory.GetDefault()).GetDefaultSigningIdentity()
   107  	if err != nil {
   108  		fmt.Println("Failed to load local signing identity:", err)
   109  		os.Exit(0)
   110  	}
   111  
   112  	var channelID string
   113  	var serverAddr string
   114  	var seek int
   115  	var quiet bool
   116  
   117  	flag.StringVar(&serverAddr, "server", fmt.Sprintf("%s:%d", conf.General.ListenAddress, conf.General.ListenPort), "The RPC server to connect to.")
   118  	flag.StringVar(&channelID, "channelID", "mychannel", "The channel ID to deliver from.")
   119  	flag.BoolVar(&quiet, "quiet", false, "Only print the block number, will not attempt to print its block contents.")
   120  	flag.IntVar(&seek, "seek", -2, "Specify the range of requested blocks."+
   121  		"Acceptable values:"+
   122  		"-2 (or -1) to start from oldest (or newest) and keep at it indefinitely."+
   123  		"N >= 0 to fetch block N only.")
   124  	flag.Parse()
   125  
   126  	if seek < -2 {
   127  		fmt.Println("Wrong seek value.")
   128  		flag.PrintDefaults()
   129  	}
   130  
   131  	conn, err := grpc.Dial(serverAddr, grpc.WithInsecure())
   132  	if err != nil {
   133  		fmt.Println("Error connecting:", err)
   134  		return
   135  	}
   136  	client, err := ab.NewAtomicBroadcastClient(conn).Deliver(context.TODO())
   137  	if err != nil {
   138  		fmt.Println("Error connecting:", err)
   139  		return
   140  	}
   141  
   142  	s := newDeliverClient(client, channelID, signer, quiet)
   143  	switch seek {
   144  	case -2:
   145  		err = s.seekOldest()
   146  	case -1:
   147  		err = s.seekNewest()
   148  	default:
   149  		err = s.seekSingle(uint64(seek))
   150  	}
   151  
   152  	if err != nil {
   153  		fmt.Println("Received error:", err)
   154  	}
   155  
   156  	s.readUntilClose()
   157  }