fabric-samples/off_chain_data/application-go/parser/block.go
Stanislav Jakuschevskij b04bda5b11
Extract block processor and store from listener
Created packages for the flat file store and the processor and moved
functions, variables and constants from listener.go to those packages.
Encapsulated everything not used outside the packages, introduced
model.go files which later might be extracted into a model package and
renamed parser/parsedBlock.go to parser/block.go.

Signed-off-by: Stanislav Jakuschevskij <stas@two-giants.com>
2025-02-24 13:14:47 +01:00

103 lines
2.4 KiB
Go

package parser
import (
"fmt"
"offChainData/utils"
"github.com/hyperledger/fabric-protos-go-apiv2/common"
"google.golang.org/protobuf/proto"
)
type Block struct {
block *common.Block
transactions []*Transaction
}
func ParseBlock(block *common.Block) *Block {
return &Block{block, nil}
}
func (b *Block) Number() uint64 {
header := utils.AssertDefined(b.block.GetHeader(), "missing block header")
return header.GetNumber()
}
func (b *Block) Transactions() []*Transaction {
return utils.Cache(func() []*Transaction {
envelopes := b.unmarshalEnvelopesFromBlockData()
commonPayloads := b.unmarshalPayloadsFrom(envelopes)
payloads := b.parse(commonPayloads)
return b.createTransactionsFrom(payloads)
})()
}
func (b *Block) unmarshalEnvelopesFromBlockData() []*common.Envelope {
result := []*common.Envelope{}
for _, blockData := range b.block.GetData().GetData() {
envelope := &common.Envelope{}
if err := proto.Unmarshal(blockData, envelope); err != nil {
panic(err)
}
result = append(result, envelope)
}
return result
}
func (*Block) unmarshalPayloadsFrom(envelopes []*common.Envelope) []*common.Payload {
result := []*common.Payload{}
for _, envelope := range envelopes {
commonPayload := &common.Payload{}
if err := proto.Unmarshal(envelope.GetPayload(), commonPayload); err != nil {
panic(err)
}
result = append(result, commonPayload)
}
return result
}
func (b *Block) parse(commonPayloads []*common.Payload) []*PayloadImpl {
validationCodes := b.extractTransactionValidationCodes()
result := []*PayloadImpl{}
for i, commonPayload := range commonPayloads {
payload := ParsePayload(
commonPayload,
int32(utils.AssertDefined(
validationCodes[i],
fmt.Sprint("missing validation code index", i),
),
),
)
if payload.IsEndorserTransaction() {
result = append(result, payload)
}
}
return result
}
func (b *Block) extractTransactionValidationCodes() []byte {
metadata := utils.AssertDefined(
b.block.GetMetadata(),
"missing block metadata",
)
return utils.AssertDefined(
metadata.GetMetadata()[common.BlockMetadataIndex_TRANSACTIONS_FILTER],
"missing transaction validation code",
)
}
func (*Block) createTransactionsFrom(payloads []*PayloadImpl) []*Transaction {
result := []*Transaction{}
for _, payload := range payloads {
result = append(result, NewTransaction(payload))
}
return result
}
// TODO remove unused?
func (b *Block) ToProto() *common.Block {
return b.block
}