github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/orderer/sample_clients/single_tx_client/single_tx_client.go (about)

     1  /*
     2  Copyright Digital Asset Holdings, LLC 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  	"fmt"
    21  	"math"
    22  	"time"
    23  
    24  	"github.com/hyperledger/fabric/common/configtx/tool/provisional"
    25  	cb "github.com/hyperledger/fabric/protos/common"
    26  	ab "github.com/hyperledger/fabric/protos/orderer"
    27  	"github.com/hyperledger/fabric/protos/utils"
    28  
    29  	"github.com/golang/protobuf/proto"
    30  	"github.com/op/go-logging"
    31  	"golang.org/x/net/context"
    32  	"google.golang.org/grpc"
    33  )
    34  
    35  var logger = logging.MustGetLogger("single_tx_client")
    36  
    37  var UPDATE byte = 0
    38  var SEND byte = 1
    39  
    40  var NEEDED_UPDATES = 2
    41  var NEEDED_SENT = 1
    42  
    43  func main() {
    44  	logger.Info("Creating an Atomic Broadcast GRPC connection.")
    45  	timeout := 4 * time.Second
    46  	clientconn, err := grpc.Dial(":7050", grpc.WithBlock(), grpc.WithTimeout(timeout), grpc.WithInsecure())
    47  	if err != nil {
    48  		logger.Errorf("Failed to connect to GRPC: %s", err)
    49  		return
    50  	}
    51  	client := ab.NewAtomicBroadcastClient(clientconn)
    52  
    53  	resultch := make(chan byte)
    54  	errorch := make(chan error)
    55  
    56  	logger.Info("Starting a goroutine waiting for ledger updates.")
    57  	go updateReceiver(resultch, errorch, client)
    58  
    59  	logger.Info("Starting a single broadcast sender goroutine.")
    60  	go broadcastSender(resultch, errorch, client)
    61  
    62  	checkResults(resultch, errorch)
    63  }
    64  
    65  func checkResults(resultch chan byte, errorch chan error) {
    66  	l := len(errorch)
    67  	for i := 0; i < l; i++ {
    68  		errres := <-errorch
    69  		logger.Error(errres)
    70  	}
    71  
    72  	updates := 0
    73  	sentBroadcast := 0
    74  	for i := 0; i < 3; i++ {
    75  		select {
    76  		case result := <-resultch:
    77  			switch result {
    78  			case UPDATE:
    79  				updates++
    80  			case SEND:
    81  				sentBroadcast++
    82  			}
    83  		case <-time.After(30 * time.Second):
    84  			continue
    85  		}
    86  	}
    87  	if updates != NEEDED_UPDATES {
    88  		logger.Errorf("We did not get all the ledger updates.")
    89  	} else if sentBroadcast != NEEDED_SENT {
    90  		logger.Errorf("We were unable to send all the broadcasts.")
    91  	} else {
    92  		logger.Info("Successfully sent and received everything.")
    93  	}
    94  }
    95  
    96  func updateReceiver(resultch chan byte, errorch chan error, client ab.AtomicBroadcastClient) {
    97  	logger.Info("{Update Receiver} Creating a ledger update delivery stream.")
    98  	dstream, err := client.Deliver(context.Background())
    99  	if err != nil {
   100  		errorch <- fmt.Errorf("Failed to get Deliver stream: %s", err)
   101  		return
   102  	}
   103  	dstream.Send(&cb.Envelope{
   104  		Payload: utils.MarshalOrPanic(&cb.Payload{
   105  			Header: &cb.Header{
   106  				ChannelHeader: utils.MarshalOrPanic(&cb.ChannelHeader{
   107  					ChannelId: provisional.TestChainID,
   108  				}),
   109  				SignatureHeader: utils.MarshalOrPanic(&cb.SignatureHeader{}),
   110  			},
   111  			Data: utils.MarshalOrPanic(&ab.SeekInfo{
   112  				Start: &ab.SeekPosition{Type: &ab.SeekPosition_Newest{
   113  					Newest: &ab.SeekNewest{}}},
   114  				Stop:     &ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: math.MaxUint64}}},
   115  				Behavior: ab.SeekInfo_BLOCK_UNTIL_READY,
   116  			}),
   117  		}),
   118  	})
   119  
   120  	logger.Info("{Update Receiver} Listening to ledger updates.")
   121  	for i := 0; i < 3; i++ {
   122  		m, inerr := dstream.Recv()
   123  		if inerr != nil {
   124  			errorch <- fmt.Errorf("Failed to receive consensus: %s", inerr)
   125  			return
   126  		}
   127  		switch b := m.Type.(type) {
   128  		case *ab.DeliverResponse_Status:
   129  			fmt.Println("Got status ", b)
   130  		case *ab.DeliverResponse_Block:
   131  			logger.Info("{Update Receiver} Received a ledger update.")
   132  			for i, tx := range b.Block.Data.Data {
   133  				pl := &cb.Payload{}
   134  				e := &cb.Envelope{}
   135  				merr1 := proto.Unmarshal(tx, e)
   136  				merr2 := proto.Unmarshal(e.Payload, pl)
   137  				if merr1 == nil && merr2 == nil {
   138  					logger.Infof("{Update Receiver} %d - %v", i+1, pl.Data)
   139  				}
   140  			}
   141  			resultch <- UPDATE
   142  		}
   143  	}
   144  	logger.Info("{Update Receiver} Exiting...")
   145  }
   146  
   147  func broadcastSender(resultch chan byte, errorch chan error, client ab.AtomicBroadcastClient) {
   148  	logger.Info("{Broadcast Sender} Waiting before sending.")
   149  	<-time.After(5 * time.Second)
   150  	bstream, err := client.Broadcast(context.Background())
   151  	if err != nil {
   152  		errorch <- fmt.Errorf("Failed to get broadcast stream: %s", err)
   153  		return
   154  	}
   155  	bs := []byte{0, 1, 2, 3}
   156  	pl := &cb.Payload{
   157  		Header: &cb.Header{
   158  			ChannelHeader: utils.MarshalOrPanic(&cb.ChannelHeader{
   159  				ChannelId: provisional.TestChainID,
   160  			}),
   161  		},
   162  		Data: bs,
   163  	}
   164  	mpl, err := proto.Marshal(pl)
   165  	if err != nil {
   166  		panic("Failed to marshal payload.")
   167  	}
   168  	bstream.Send(&cb.Envelope{Payload: mpl})
   169  	logger.Infof("{Broadcast Sender} Broadcast sent: %v", bs)
   170  	logger.Info("{Broadcast Sender} Exiting...")
   171  	resultch <- SEND
   172  }