github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/common/ledger/blockledger/util.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package blockledger
     8  
     9  import (
    10  	"github.com/golang/protobuf/proto"
    11  	"github.com/hechain20/hechain/common/flogging"
    12  	"github.com/hechain20/hechain/protoutil"
    13  	cb "github.com/hyperledger/fabric-protos-go/common"
    14  	ab "github.com/hyperledger/fabric-protos-go/orderer"
    15  )
    16  
    17  var logger = flogging.MustGetLogger("common.ledger.blockledger.util")
    18  
    19  var closedChan chan struct{}
    20  
    21  func init() {
    22  	closedChan = make(chan struct{})
    23  	close(closedChan)
    24  }
    25  
    26  // NotFoundErrorIterator simply always returns an error of cb.Status_NOT_FOUND,
    27  // and is generally useful for implementations of the Reader interface
    28  type NotFoundErrorIterator struct{}
    29  
    30  // Next returns nil, cb.Status_NOT_FOUND
    31  func (nfei *NotFoundErrorIterator) Next() (*cb.Block, cb.Status) {
    32  	return nil, cb.Status_NOT_FOUND
    33  }
    34  
    35  // ReadyChan returns a closed channel
    36  func (nfei *NotFoundErrorIterator) ReadyChan() <-chan struct{} {
    37  	return closedChan
    38  }
    39  
    40  // Close does nothing
    41  func (nfei *NotFoundErrorIterator) Close() {}
    42  
    43  // CreateNextBlock provides a utility way to construct the next block from
    44  // contents and metadata for a given ledger
    45  // XXX This will need to be modified to accept marshaled envelopes
    46  //     to accommodate non-deterministic marshaling
    47  func CreateNextBlock(rl Reader, messages []*cb.Envelope) *cb.Block {
    48  	var nextBlockNumber uint64
    49  	var previousBlockHash []byte
    50  	var err error
    51  
    52  	if rl.Height() > 0 {
    53  		it, _ := rl.Iterator(&ab.SeekPosition{
    54  			Type: &ab.SeekPosition_Newest{
    55  				Newest: &ab.SeekNewest{},
    56  			},
    57  		})
    58  		block, status := it.Next()
    59  		if status != cb.Status_SUCCESS {
    60  			panic("Error seeking to newest block for chain with non-zero height")
    61  		}
    62  		nextBlockNumber = block.Header.Number + 1
    63  		previousBlockHash = protoutil.BlockHeaderHash(block.Header)
    64  	}
    65  
    66  	data := &cb.BlockData{
    67  		Data: make([][]byte, len(messages)),
    68  	}
    69  
    70  	for i, msg := range messages {
    71  		data.Data[i], err = proto.Marshal(msg)
    72  		if err != nil {
    73  			panic(err)
    74  		}
    75  	}
    76  
    77  	block := protoutil.NewBlock(nextBlockNumber, previousBlockHash)
    78  	block.Header.DataHash = protoutil.BlockDataHash(data)
    79  	block.Data = data
    80  
    81  	return block
    82  }
    83  
    84  // GetBlock is a utility method for retrieving a single block
    85  func GetBlock(rl Reader, index uint64) *cb.Block {
    86  	iterator, _ := rl.Iterator(&ab.SeekPosition{
    87  		Type: &ab.SeekPosition_Specified{
    88  			Specified: &ab.SeekSpecified{Number: index},
    89  		},
    90  	})
    91  	if iterator == nil {
    92  		return nil
    93  	}
    94  	defer iterator.Close()
    95  	block, status := iterator.Next()
    96  	if status != cb.Status_SUCCESS {
    97  		return nil
    98  	}
    99  	return block
   100  }
   101  
   102  func GetBlockByNumber(rl Reader, blockNum uint64) (*cb.Block, error) {
   103  	logger.Debugw("Retrieving block", "blockNum", blockNum)
   104  	return rl.RetrieveBlockByNumber(blockNum)
   105  }