Implement block parsing

Removed Block and Transaction interfaces and unused statusCode function.
Using the struct instead of the interfaces now.

Signed-off-by: Stanislav Jakuschevskij <stas@two-giants.com>
This commit is contained in:
Stanislav Jakuschevskij 2024-12-07 16:20:40 +01:00
parent 2c43e03591
commit 8ae2909b9b
No known key found for this signature in database
GPG key ID: 78195D2E6998E2EB
4 changed files with 67 additions and 67 deletions

View file

@ -1,23 +1,20 @@
package parser package parser
import ( import (
"fmt"
"offChainData/utils" "offChainData/utils"
"github.com/hyperledger/fabric-protos-go-apiv2/common" "github.com/hyperledger/fabric-protos-go-apiv2/common"
"github.com/hyperledger/fabric-protos-go-apiv2/peer"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
) )
type Block struct { type Block struct {
block *common.Block block *common.Block
validationCodes []byte transactions []*Transaction
transactions []Transaction
} }
func ParseBlock(block *common.Block) Block { func ParseBlock(block *common.Block) *Block {
validationCodes := extractTransactionValidationCodes(block) return &Block{block, nil}
return Block{block, validationCodes, nil}
} }
func (b *Block) Number() uint64 { func (b *Block) Number() uint64 {
@ -25,58 +22,53 @@ func (b *Block) Number() uint64 {
return header.GetNumber() return header.GetNumber()
} }
// TODO: needs cache, getPayloads, parsePayload // TODO: needs cache; decompose
func (b *Block) Transactions() []Transaction { func (b *Block) Transactions() []*Transaction {
return nil envelopes := []*common.Envelope{}
} for _, blockData := range b.block.GetData().GetData() {
func (b *Block) ToProto() *common.Block {
return nil
}
func (b *Block) payloads() []*common.Payload {
var payloads []*common.Payload
for _, envelopeBytes := range b.block.GetData().GetData() {
envelope := &common.Envelope{} envelope := &common.Envelope{}
if err := proto.Unmarshal(envelopeBytes, envelope); err != nil { if err := proto.Unmarshal(blockData, envelope); err != nil {
panic(err) panic(err)
} }
envelopes = append(envelopes, envelope)
}
payload := &common.Payload{} commonPayloads := []*common.Payload{}
if err := proto.Unmarshal(envelope.Payload, payload); err != nil { for _, envelope := range envelopes {
commonPayload := &common.Payload{}
if err := proto.Unmarshal(envelope.GetPayload(), commonPayload); err != nil {
panic(err) panic(err)
} }
commonPayloads = append(commonPayloads, commonPayload)
payloads = append(payloads, payload)
} }
return payloads validationCodes := b.extractTransactionValidationCodes()
payloads := []*PayloadImpl{}
for i, commonPayload := range commonPayloads {
payload := ParsePayload(
commonPayload,
int32(utils.AssertDefined(
validationCodes[i],
fmt.Sprint("missing validation code index", i),
),
),
)
if payload.IsEndorserTransaction() {
payloads = append(payloads, payload)
}
}
result := []*Transaction{}
for _, payload := range payloads {
result = append(result, NewTransaction(payload))
}
return result
} }
// TODO not sure about this func (b *Block) extractTransactionValidationCodes() []byte {
func (pb *Block) statusCode(txIndex int) peer.TxValidationCode {
blockMetadata := utils.AssertDefined(
pb.block.GetMetadata(),
"missing block metadata",
)
metadata := blockMetadata.GetMetadata()
if int(common.BlockMetadataIndex_TRANSACTIONS_FILTER) >= len(metadata) {
return peer.TxValidationCode_INVALID_OTHER_REASON
}
statusCodes := metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER]
if txIndex >= len(statusCodes) {
return peer.TxValidationCode_INVALID_OTHER_REASON
}
return peer.TxValidationCode(statusCodes[txIndex])
}
func extractTransactionValidationCodes(block *common.Block) []byte {
metadata := utils.AssertDefined( metadata := utils.AssertDefined(
block.GetMetadata(), b.block.GetMetadata(),
"missing block metadata", "missing block metadata",
) )
@ -85,3 +77,8 @@ func extractTransactionValidationCodes(block *common.Block) []byte {
"missing transaction validation code", "missing transaction validation code",
) )
} }
// TODO remove unused?
func (b *Block) ToProto() *common.Block {
return b.block
}

View file

@ -9,6 +9,7 @@ import (
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
) )
// TODO remove interface, use struct; encapsulate
type Payload interface { type Payload interface {
ChannelHeader() *common.ChannelHeader ChannelHeader() *common.ChannelHeader
EndorserTransaction() EndorserTransaction EndorserTransaction() EndorserTransaction
@ -77,6 +78,7 @@ func (p *PayloadImpl) IsValid() bool {
return p.statusCode == int32(peer.TxValidationCode_VALID) return p.statusCode == int32(peer.TxValidationCode_VALID)
} }
// TODO remove unused
func (p *PayloadImpl) ToProto() *common.Payload { func (p *PayloadImpl) ToProto() *common.Payload {
return p.payload return p.payload
} }

View file

@ -6,6 +6,7 @@ import (
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
) )
// TODO remove interface, use struct; encapsulate; extract into file
type ReadWriteSet interface { type ReadWriteSet interface {
NamespaceReadWriteSets() []NamespaceReadWriteSet NamespaceReadWriteSets() []NamespaceReadWriteSet
ToProto() *rwset.TxReadWriteSet ToProto() *rwset.TxReadWriteSet
@ -28,10 +29,12 @@ func (p *ReadWriteSetImpl) NamespaceReadWriteSets() []NamespaceReadWriteSet {
return result return result
} }
// TODO remove unused
func (p *ReadWriteSetImpl) ToProto() *rwset.TxReadWriteSet { func (p *ReadWriteSetImpl) ToProto() *rwset.TxReadWriteSet {
return p.readWriteSet return p.readWriteSet
} }
// TODO remove interface, use struct
type NamespaceReadWriteSet interface { type NamespaceReadWriteSet interface {
Namespace() string Namespace() string
ReadWriteSet() *kvrwset.KVRWSet ReadWriteSet() *kvrwset.KVRWSet
@ -60,6 +63,7 @@ func (p *NamespaceReadWriteSetImpl) ReadWriteSet() *kvrwset.KVRWSet {
return &result return &result
} }
// TODO remove unused
func (p *NamespaceReadWriteSetImpl) ToProto() *rwset.NsReadWriteSet { func (p *NamespaceReadWriteSetImpl) ToProto() *rwset.NsReadWriteSet {
return p.nsReadWriteSet return p.nsReadWriteSet
} }

View file

@ -11,28 +11,20 @@ import (
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
) )
type Transaction interface { type Transaction struct {
ChannelHeader() *common.ChannelHeader
Creator() identity.Identity
ValidationCode() int32
IsValid() bool
NamespaceReadWriteSets() []NamespaceReadWriteSet
ToProto() *common.Payload
}
type TransactionImpl struct {
payload Payload payload Payload
} }
func NewTransactionImpl(payload Payload) *TransactionImpl { func NewTransaction(payload Payload) *Transaction {
return &TransactionImpl{payload} return &Transaction{payload}
} }
func (t *TransactionImpl) ChannelHeader() *common.ChannelHeader { func (t *Transaction) ChannelHeader() *common.ChannelHeader {
return t.payload.ChannelHeader() return t.payload.ChannelHeader()
} }
func (t *TransactionImpl) Creator() identity.Identity { // TODO remove unused?
func (t *Transaction) Creator() identity.Identity {
creator := &msp.SerializedIdentity{} creator := &msp.SerializedIdentity{}
if err := proto.Unmarshal(t.payload.SignatureHeader().GetCreator(), creator); err != nil { if err := proto.Unmarshal(t.payload.SignatureHeader().GetCreator(), creator); err != nil {
panic(err) panic(err)
@ -41,7 +33,7 @@ func (t *TransactionImpl) Creator() identity.Identity {
return &identityImpl{creator} return &identityImpl{creator}
} }
func (t *TransactionImpl) NamespaceReadWriteSets() []NamespaceReadWriteSet { func (t *Transaction) NamespaceReadWriteSets() []NamespaceReadWriteSet {
result := []NamespaceReadWriteSet{} result := []NamespaceReadWriteSet{}
for _, readWriteSet := range t.payload.EndorserTransaction().ReadWriteSets() { for _, readWriteSet := range t.payload.EndorserTransaction().ReadWriteSets() {
result = append(result, readWriteSet.NamespaceReadWriteSets()...) result = append(result, readWriteSet.NamespaceReadWriteSets()...)
@ -50,18 +42,22 @@ func (t *TransactionImpl) NamespaceReadWriteSets() []NamespaceReadWriteSet {
return result return result
} }
func (t *TransactionImpl) ValidationCode() int32 { // TODO remove unused?
func (t *Transaction) ValidationCode() int32 {
return t.payload.TransactionValidationCode() return t.payload.TransactionValidationCode()
} }
func (t *TransactionImpl) IsValid() bool { // TODO remove unused?
func (t *Transaction) IsValid() bool {
return t.payload.IsValid() return t.payload.IsValid()
} }
func (t *TransactionImpl) ToProto() *common.Payload { // TODO remove unused?
func (t *Transaction) ToProto() *common.Payload {
return t.payload.ToProto() return t.payload.ToProto()
} }
// TODO remove interface, use struct; encapsulate; extract into file
type EndorserTransaction interface { type EndorserTransaction interface {
ReadWriteSets() []ReadWriteSet ReadWriteSets() []ReadWriteSet
ToProto() *peer.Transaction ToProto() *peer.Transaction
@ -164,6 +160,7 @@ func (*EndorserTransactionImpl) parseReadWriteSets(txReadWriteSets []*rwset.TxRe
return result return result
} }
// TODO remove unused
func (p *EndorserTransactionImpl) ToProto() *peer.Transaction { func (p *EndorserTransactionImpl) ToProto() *peer.Transaction {
return p.transaction return p.transaction
} }