github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/orderer/sample_clients/deliver_stdout/client.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8                   http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  import (
    20  	"flag"
    21  	"fmt"
    22  	"math"
    23  
    24  	"github.com/hyperledger/fabric/common/configtx/tool/provisional"
    25  	"github.com/hyperledger/fabric/orderer/localconfig"
    26  	cb "github.com/hyperledger/fabric/protos/common"
    27  	ab "github.com/hyperledger/fabric/protos/orderer"
    28  	"github.com/hyperledger/fabric/protos/utils"
    29  	"golang.org/x/net/context"
    30  	"google.golang.org/grpc"
    31  )
    32  
    33  var (
    34  	oldest  = &ab.SeekPosition{Type: &ab.SeekPosition_Oldest{Oldest: &ab.SeekOldest{}}}
    35  	newest  = &ab.SeekPosition{Type: &ab.SeekPosition_Newest{Newest: &ab.SeekNewest{}}}
    36  	maxStop = &ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: math.MaxUint64}}}
    37  )
    38  
    39  type deliverClient struct {
    40  	client  ab.AtomicBroadcast_DeliverClient
    41  	chainID string
    42  }
    43  
    44  func newDeliverClient(client ab.AtomicBroadcast_DeliverClient, chainID string) *deliverClient {
    45  	return &deliverClient{client: client, chainID: chainID}
    46  }
    47  
    48  func seekHelper(chainID string, start *ab.SeekPosition, stop *ab.SeekPosition) *cb.Envelope {
    49  	return &cb.Envelope{
    50  		Payload: utils.MarshalOrPanic(&cb.Payload{
    51  			Header: &cb.Header{
    52  				ChannelHeader: utils.MarshalOrPanic(&cb.ChannelHeader{
    53  					ChannelId: chainID,
    54  				}),
    55  				SignatureHeader: utils.MarshalOrPanic(&cb.SignatureHeader{}),
    56  			},
    57  
    58  			Data: utils.MarshalOrPanic(&ab.SeekInfo{
    59  				Start:    start,
    60  				Stop:     stop,
    61  				Behavior: ab.SeekInfo_BLOCK_UNTIL_READY,
    62  			}),
    63  		}),
    64  	}
    65  }
    66  
    67  func (r *deliverClient) seekOldest() error {
    68  	return r.client.Send(seekHelper(r.chainID, oldest, maxStop))
    69  }
    70  
    71  func (r *deliverClient) seekNewest() error {
    72  	return r.client.Send(seekHelper(r.chainID, newest, maxStop))
    73  }
    74  
    75  func (r *deliverClient) seekSingle(blockNumber uint64) error {
    76  	specific := &ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: blockNumber}}}
    77  	return r.client.Send(seekHelper(r.chainID, specific, specific))
    78  }
    79  
    80  func (r *deliverClient) readUntilClose() {
    81  	for {
    82  		msg, err := r.client.Recv()
    83  		if err != nil {
    84  			fmt.Println("Error receiving:", err)
    85  			return
    86  		}
    87  
    88  		switch t := msg.Type.(type) {
    89  		case *ab.DeliverResponse_Status:
    90  			fmt.Println("Got status ", t)
    91  			return
    92  		case *ab.DeliverResponse_Block:
    93  			fmt.Println("Received block: ", t.Block)
    94  		}
    95  	}
    96  }
    97  
    98  func main() {
    99  	config := config.Load()
   100  
   101  	var chainID string
   102  	var serverAddr string
   103  	var seek int
   104  
   105  	flag.StringVar(&serverAddr, "server", fmt.Sprintf("%s:%d", config.General.ListenAddress, config.General.ListenPort), "The RPC server to connect to.")
   106  	flag.StringVar(&chainID, "chainID", provisional.TestChainID, "The chain ID to deliver from.")
   107  	flag.IntVar(&seek, "seek", -2, "Specify the range of requested blocks."+
   108  		"Acceptable values:"+
   109  		"-2 (or -1) to start from oldest (or newest) and keep at it indefinitely."+
   110  		"N >= 0 to fetch block N only.")
   111  	flag.Parse()
   112  
   113  	if seek < -2 {
   114  		fmt.Println("Wrong seek value.")
   115  		flag.PrintDefaults()
   116  	}
   117  
   118  	conn, err := grpc.Dial(serverAddr, grpc.WithInsecure())
   119  	if err != nil {
   120  		fmt.Println("Error connecting:", err)
   121  		return
   122  	}
   123  	client, err := ab.NewAtomicBroadcastClient(conn).Deliver(context.TODO())
   124  	if err != nil {
   125  		fmt.Println("Error connecting:", err)
   126  		return
   127  	}
   128  
   129  	s := newDeliverClient(client, chainID)
   130  	switch seek {
   131  	case -2:
   132  		err = s.seekOldest()
   133  	case -1:
   134  		err = s.seekNewest()
   135  	default:
   136  		err = s.seekSingle(uint64(seek))
   137  	}
   138  
   139  	if err != nil {
   140  		fmt.Println("Received error:", err)
   141  	}
   142  
   143  	s.readUntilClose()
   144  }