github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/internal/pkg/gateway/event/block.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  SPDX-License-Identifier: Apache-2.0
     4  */
     5  
     6  package event
     7  
     8  import (
     9  	"github.com/golang/protobuf/proto"
    10  	"github.com/hyperledger/fabric-protos-go/common"
    11  	"github.com/hyperledger/fabric-protos-go/peer"
    12  )
    13  
    14  type Block struct {
    15  	block        *common.Block
    16  	transactions []*Transaction
    17  }
    18  
    19  func NewBlock(block *common.Block) *Block {
    20  	return &Block{
    21  		block: block,
    22  	}
    23  }
    24  
    25  func (b *Block) Number() uint64 {
    26  	return b.block.GetHeader().GetNumber()
    27  }
    28  
    29  func (b *Block) Transactions() ([]*Transaction, error) {
    30  	var err error
    31  
    32  	if b.transactions == nil {
    33  		b.transactions, err = b.readTransactions()
    34  	}
    35  
    36  	return b.transactions, err
    37  }
    38  
    39  func (b *Block) readTransactions() ([]*Transaction, error) {
    40  	transactions := make([]*Transaction, 0)
    41  
    42  	txPayloads, err := b.payloads()
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  
    47  	for i, payload := range txPayloads {
    48  		header := &common.ChannelHeader{}
    49  		if err := proto.Unmarshal(payload.GetHeader().GetChannelHeader(), header); err != nil {
    50  			return nil, err
    51  		}
    52  
    53  		if header.GetType() == int32(common.HeaderType_ENDORSER_TRANSACTION) {
    54  			transaction := &Transaction{
    55  				parent:    b,
    56  				payload:   payload,
    57  				id:        header.GetTxId(),
    58  				timestamp: header.GetTimestamp(),
    59  				status:    b.statusCode(i),
    60  			}
    61  			transactions = append(transactions, transaction)
    62  		}
    63  	}
    64  
    65  	return transactions, nil
    66  }
    67  
    68  func (b *Block) payloads() ([]*common.Payload, error) {
    69  	var payloads []*common.Payload
    70  
    71  	for _, envelopeBytes := range b.block.GetData().GetData() {
    72  		envelope := &common.Envelope{}
    73  		if err := proto.Unmarshal(envelopeBytes, envelope); err != nil {
    74  			return nil, err
    75  		}
    76  
    77  		payload := &common.Payload{}
    78  		if err := proto.Unmarshal(envelope.Payload, payload); err != nil {
    79  			return nil, err
    80  		}
    81  
    82  		payloads = append(payloads, payload)
    83  	}
    84  
    85  	return payloads, nil
    86  }
    87  
    88  func (b *Block) statusCode(txIndex int) peer.TxValidationCode {
    89  	metadata := b.block.GetMetadata().GetMetadata()
    90  	if int(common.BlockMetadataIndex_TRANSACTIONS_FILTER) >= len(metadata) {
    91  		return peer.TxValidationCode_INVALID_OTHER_REASON
    92  	}
    93  
    94  	statusCodes := metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER]
    95  	if txIndex >= len(statusCodes) {
    96  		return peer.TxValidationCode_INVALID_OTHER_REASON
    97  	}
    98  
    99  	return peer.TxValidationCode(statusCodes[txIndex])
   100  }