Refactor parser package, decompose files

Every struct was put in its own file. Every method which is not used
outside the parser package was given package scope. All interfaces were
removed, they are implemented by the structs which are now used
everywhere needed as return values. There is no clear benefit of using
interfaces in this sample.

Signed-off-by: Stanislav Jakuschevskij <stas@two-giants.com>
This commit is contained in:
Stanislav Jakuschevskij 2025-01-01 18:01:19 +01:00
parent 624f65da12
commit 81efd2cc61
No known key found for this signature in database
GPG key ID: 78195D2E6998E2EB
11 changed files with 204 additions and 305 deletions

View file

@ -58,11 +58,11 @@ func (*Block) unmarshalPayloadsFrom(envelopes []*common.Envelope) []*common.Payl
return result return result
} }
func (b *Block) parse(commonPayloads []*common.Payload) []*PayloadImpl { func (b *Block) parse(commonPayloads []*common.Payload) []*payload {
validationCodes := b.extractTransactionValidationCodes() validationCodes := b.extractTransactionValidationCodes()
result := []*PayloadImpl{} result := []*payload{}
for i, commonPayload := range commonPayloads { for i, commonPayload := range commonPayloads {
payload := ParsePayload( payload := parsePayload(
commonPayload, commonPayload,
int32(utils.AssertDefined( int32(utils.AssertDefined(
validationCodes[i], validationCodes[i],
@ -70,7 +70,7 @@ func (b *Block) parse(commonPayloads []*common.Payload) []*PayloadImpl {
), ),
), ),
) )
if payload.IsEndorserTransaction() { if payload.isEndorserTransaction() {
result = append(result, payload) result = append(result, payload)
} }
} }
@ -89,15 +89,10 @@ func (b *Block) extractTransactionValidationCodes() []byte {
) )
} }
func (*Block) createTransactionsFrom(payloads []*PayloadImpl) []*Transaction { func (*Block) createTransactionsFrom(payloads []*payload) []*Transaction {
result := []*Transaction{} result := []*Transaction{}
for _, payload := range payloads { for _, payload := range payloads {
result = append(result, NewTransaction(payload)) result = append(result, newTransaction(payload))
} }
return result return result
} }
// TODO remove unused?
func (b *Block) ToProto() *common.Block {
return b.block
}

View file

@ -1,11 +1,10 @@
package parser_test package parser
import ( import (
"encoding/json" "encoding/json"
"testing" "testing"
atb "offChainData/contract" atb "offChainData/contract"
"offChainData/parser"
"github.com/hyperledger/fabric-protos-go-apiv2/ledger/rwset" "github.com/hyperledger/fabric-protos-go-apiv2/ledger/rwset"
"github.com/hyperledger/fabric-protos-go-apiv2/ledger/rwset/kvrwset" "github.com/hyperledger/fabric-protos-go-apiv2/ledger/rwset/kvrwset"
@ -35,13 +34,13 @@ func Test_GetReadWriteSetsFromEndorserTransaction(t *testing.T) {
}, },
} }
parsedEndorserTransaction := parser.ParseEndorserTransaction(transaction) parsedEndorserTransaction := parseEndorserTransaction(transaction)
if len(parsedEndorserTransaction.ReadWriteSets()) != 1 { if len(parsedEndorserTransaction.readWriteSets()) != 1 {
t.Fatal("expected 1 ReadWriteSet, got", len(parsedEndorserTransaction.ReadWriteSets())) t.Fatal("expected 1 ReadWriteSet, got", len(parsedEndorserTransaction.readWriteSets()))
} }
assertReadWriteSet( assertReadWriteSet(
parsedEndorserTransaction.ReadWriteSets()[0].NamespaceReadWriteSets()[0], parsedEndorserTransaction.readWriteSets()[0].namespaceReadWriteSets()[0],
expectedNamespace, expectedNamespace,
expectedAsset, expectedAsset,
t, t,
@ -49,7 +48,7 @@ func Test_GetReadWriteSetsFromEndorserTransaction(t *testing.T) {
} }
func assertReadWriteSet( func assertReadWriteSet(
parsedNsRwSet parser.NamespaceReadWriteSet, parsedNsRwSet *NamespaceReadWriteSet,
expectedNamespace string, expectedNamespace string,
expectedAsset atb.Asset, expectedAsset atb.Asset,
t *testing.T, t *testing.T,
@ -80,16 +79,16 @@ func Test_ReadWriteSetWrapping(t *testing.T) {
NsRwset: []*rwset.NsReadWriteSet{nsReadWriteSetFake}, NsRwset: []*rwset.NsReadWriteSet{nsReadWriteSetFake},
} }
parsedRwSet := parser.ParseReadWriteSet(txReadWriteSetFake) parsedRwSet := parseReadWriteSet(txReadWriteSetFake)
if len(parsedRwSet.NamespaceReadWriteSets()) != 1 { if len(parsedRwSet.namespaceReadWriteSets()) != 1 {
t.Fatalf("Expected 1 NamespaceReadWriteSet, got %d", len(parsedRwSet.NamespaceReadWriteSets())) t.Fatalf("Expected 1 NamespaceReadWriteSet, got %d", len(parsedRwSet.namespaceReadWriteSets()))
} }
} }
func Test_NamespaceReadWriteSetParsing(t *testing.T) { func Test_NamespaceReadWriteSetParsing(t *testing.T) {
nsReadWriteSetFake, expectedNamespace, expectedAsset := nsReadWriteSetFake() nsReadWriteSetFake, expectedNamespace, expectedAsset := nsReadWriteSetFake()
parsedNsRwSet := parser.ParseNamespaceReadWriteSet(nsReadWriteSetFake) parsedNsRwSet := parseNamespaceReadWriteSet(nsReadWriteSetFake)
assertReadWriteSet( assertReadWriteSet(
parsedNsRwSet, parsedNsRwSet,
expectedNamespace, expectedNamespace,

View file

@ -0,0 +1,105 @@
package parser
import (
"offChainData/utils"
"github.com/hyperledger/fabric-protos-go-apiv2/ledger/rwset"
"github.com/hyperledger/fabric-protos-go-apiv2/peer"
"google.golang.org/protobuf/proto"
)
type endorserTransaction struct {
transaction *peer.Transaction
}
func parseEndorserTransaction(transaction *peer.Transaction) *endorserTransaction {
return &endorserTransaction{transaction}
}
func (p *endorserTransaction) readWriteSets() []*readWriteSet {
return utils.Cache(func() []*readWriteSet {
chaincodeActionPayloads := p.unmarshalChaincodeActionPayloads()
chaincodeEndorsedActions := p.extractChaincodeEndorsedActionsFrom(chaincodeActionPayloads)
proposalResponsePayloads := p.unmarshalProposalResponsePayloadsFrom(chaincodeEndorsedActions)
chaincodeActions := p.unmarshalChaincodeActionsFrom(proposalResponsePayloads)
txReadWriteSets := p.unmarshalTxReadWriteSetsFrom(chaincodeActions)
return p.parseReadWriteSets(txReadWriteSets)
})()
}
func (p *endorserTransaction) unmarshalChaincodeActionPayloads() []*peer.ChaincodeActionPayload {
result := []*peer.ChaincodeActionPayload{}
for _, transactionAction := range p.transaction.GetActions() {
chaincodeActionPayload := &peer.ChaincodeActionPayload{}
if err := proto.Unmarshal(transactionAction.GetPayload(), chaincodeActionPayload); err != nil {
panic(err)
}
result = append(result, chaincodeActionPayload)
}
return result
}
func (*endorserTransaction) extractChaincodeEndorsedActionsFrom(chaincodeActionPayloads []*peer.ChaincodeActionPayload) []*peer.ChaincodeEndorsedAction {
result := []*peer.ChaincodeEndorsedAction{}
for _, payload := range chaincodeActionPayloads {
result = append(
result,
utils.AssertDefined(
payload.GetAction(),
"missing chaincode endorsed action",
),
)
}
return result
}
func (*endorserTransaction) unmarshalProposalResponsePayloadsFrom(chaincodeEndorsedActions []*peer.ChaincodeEndorsedAction) []*peer.ProposalResponsePayload {
result := []*peer.ProposalResponsePayload{}
for _, endorsedAction := range chaincodeEndorsedActions {
proposalResponsePayload := &peer.ProposalResponsePayload{}
if err := proto.Unmarshal(endorsedAction.GetProposalResponsePayload(), proposalResponsePayload); err != nil {
panic(err)
}
result = append(result, proposalResponsePayload)
}
return result
}
func (*endorserTransaction) unmarshalChaincodeActionsFrom(proposalResponsePayloads []*peer.ProposalResponsePayload) []*peer.ChaincodeAction {
result := []*peer.ChaincodeAction{}
for _, proposalResponsePayload := range proposalResponsePayloads {
chaincodeAction := &peer.ChaincodeAction{}
if err := proto.Unmarshal(proposalResponsePayload.GetExtension(), chaincodeAction); err != nil {
panic(err)
}
result = append(result, chaincodeAction)
}
return result
}
func (*endorserTransaction) unmarshalTxReadWriteSetsFrom(chaincodeActions []*peer.ChaincodeAction) []*rwset.TxReadWriteSet {
result := []*rwset.TxReadWriteSet{}
for _, chaincodeAction := range chaincodeActions {
txReadWriteSet := &rwset.TxReadWriteSet{}
if err := proto.Unmarshal(chaincodeAction.GetResults(), txReadWriteSet); err != nil {
continue
}
result = append(result, txReadWriteSet)
}
return result
}
func (*endorserTransaction) parseReadWriteSets(txReadWriteSets []*rwset.TxReadWriteSet) []*readWriteSet {
result := []*readWriteSet{}
for _, txReadWriteSet := range txReadWriteSets {
parsedReadWriteSet := parseReadWriteSet(txReadWriteSet)
result = append(result, parsedReadWriteSet)
}
return result
}

View file

@ -1,16 +0,0 @@
package parser
import "github.com/hyperledger/fabric-protos-go-apiv2/msp"
// Implements identity.Identity Interface
type identityImpl struct {
creator *msp.SerializedIdentity
}
func (i *identityImpl) MspID() string {
return i.creator.GetMspid()
}
func (i *identityImpl) Credentials() []byte {
return i.creator.GetIdBytes()
}

View file

@ -0,0 +1,32 @@
package parser
import (
"offChainData/utils"
"github.com/hyperledger/fabric-protos-go-apiv2/ledger/rwset"
"github.com/hyperledger/fabric-protos-go-apiv2/ledger/rwset/kvrwset"
"google.golang.org/protobuf/proto"
)
type NamespaceReadWriteSet struct {
nsReadWriteSet *rwset.NsReadWriteSet
}
func parseNamespaceReadWriteSet(nsRwSet *rwset.NsReadWriteSet) *NamespaceReadWriteSet {
return &NamespaceReadWriteSet{nsRwSet}
}
func (p *NamespaceReadWriteSet) Namespace() string {
return p.nsReadWriteSet.GetNamespace()
}
func (p *NamespaceReadWriteSet) ReadWriteSet() *kvrwset.KVRWSet {
return utils.Cache(func() *kvrwset.KVRWSet {
result := kvrwset.KVRWSet{}
if err := proto.Unmarshal(p.nsReadWriteSet.GetRwset(), &result); err != nil {
panic(err)
}
return &result
})()
}

View file

@ -9,29 +9,18 @@ import (
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
) )
// TODO remove interface, use struct; encapsulate type payload struct {
type Payload interface { commonPayload *common.Payload
ChannelHeader() *common.ChannelHeader statusCode int32
EndorserTransaction() EndorserTransaction
SignatureHeader() *common.SignatureHeader
TransactionValidationCode() int32
IsEndorserTransaction() bool
IsValid() bool
ToProto() *common.Payload
} }
type PayloadImpl struct { func parsePayload(commonPayload *common.Payload, statusCode int32) *payload {
payload *common.Payload return &payload{commonPayload, statusCode}
statusCode int32
} }
func ParsePayload(payload *common.Payload, statusCode int32) *PayloadImpl { func (p *payload) channelHeader() *common.ChannelHeader {
return &PayloadImpl{payload, statusCode}
}
func (p *PayloadImpl) ChannelHeader() *common.ChannelHeader {
return utils.Cache(func() *common.ChannelHeader { return utils.Cache(func() *common.ChannelHeader {
header := utils.AssertDefined(p.payload.GetHeader(), "missing payload header") header := utils.AssertDefined(p.commonPayload.GetHeader(), "missing payload header")
result := &common.ChannelHeader{} result := &common.ChannelHeader{}
if err := proto.Unmarshal(header.GetChannelHeader(), result); err != nil { if err := proto.Unmarshal(header.GetChannelHeader(), result); err != nil {
@ -42,45 +31,23 @@ func (p *PayloadImpl) ChannelHeader() *common.ChannelHeader {
})() })()
} }
func (p *PayloadImpl) EndorserTransaction() EndorserTransaction { func (p *payload) endorserTransaction() *endorserTransaction {
if !p.IsEndorserTransaction() { if !p.isEndorserTransaction() {
panic(fmt.Errorf("unexpected payload type: %d", p.ChannelHeader().GetType())) panic(fmt.Errorf("unexpected payload type: %d", p.channelHeader().GetType()))
} }
result := &peer.Transaction{} result := &peer.Transaction{}
if err := proto.Unmarshal(p.payload.GetData(), result); err != nil { if err := proto.Unmarshal(p.commonPayload.GetData(), result); err != nil {
panic(err) panic(err)
} }
return ParseEndorserTransaction(result) return parseEndorserTransaction(result)
} }
func (p *PayloadImpl) SignatureHeader() *common.SignatureHeader { func (p *payload) isEndorserTransaction() bool {
return utils.Cache(func() *common.SignatureHeader { return p.channelHeader().GetType() == int32(common.HeaderType_ENDORSER_TRANSACTION)
header := utils.AssertDefined(p.payload.GetHeader(), "missing payload header")
result := &common.SignatureHeader{}
if err := proto.Unmarshal(header.GetSignatureHeader(), result); err != nil {
panic(err)
}
return result
})()
} }
func (p *PayloadImpl) TransactionValidationCode() int32 { func (p *payload) isValid() bool {
return p.statusCode
}
func (p *PayloadImpl) IsEndorserTransaction() bool {
return p.ChannelHeader().GetType() == int32(common.HeaderType_ENDORSER_TRANSACTION)
}
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 {
return p.payload
}

View file

@ -1,72 +1,22 @@
package parser package parser
import ( import (
"offChainData/utils"
"github.com/hyperledger/fabric-protos-go-apiv2/ledger/rwset" "github.com/hyperledger/fabric-protos-go-apiv2/ledger/rwset"
"github.com/hyperledger/fabric-protos-go-apiv2/ledger/rwset/kvrwset"
"google.golang.org/protobuf/proto"
) )
// TODO remove interface, use struct; encapsulate; extract into file type readWriteSet struct {
type ReadWriteSet interface {
NamespaceReadWriteSets() []NamespaceReadWriteSet
ToProto() *rwset.TxReadWriteSet
}
type ReadWriteSetImpl struct {
readWriteSet *rwset.TxReadWriteSet readWriteSet *rwset.TxReadWriteSet
} }
func ParseReadWriteSet(rwSet *rwset.TxReadWriteSet) *ReadWriteSetImpl { func parseReadWriteSet(rwSet *rwset.TxReadWriteSet) *readWriteSet {
return &ReadWriteSetImpl{rwSet} return &readWriteSet{rwSet}
} }
func (p *ReadWriteSetImpl) NamespaceReadWriteSets() []NamespaceReadWriteSet { func (p *readWriteSet) namespaceReadWriteSets() []*NamespaceReadWriteSet {
result := []NamespaceReadWriteSet{} result := []*NamespaceReadWriteSet{}
for _, nsReadWriteSet := range p.readWriteSet.GetNsRwset() { for _, nsReadWriteSet := range p.readWriteSet.GetNsRwset() {
parsedNamespaceReadWriteSet := ParseNamespaceReadWriteSet(nsReadWriteSet) parsedNamespaceReadWriteSet := parseNamespaceReadWriteSet(nsReadWriteSet)
result = append(result, parsedNamespaceReadWriteSet) result = append(result, parsedNamespaceReadWriteSet)
} }
return result return result
} }
// TODO remove unused
func (p *ReadWriteSetImpl) ToProto() *rwset.TxReadWriteSet {
return p.readWriteSet
}
// TODO remove interface, use struct
type NamespaceReadWriteSet interface {
Namespace() string
ReadWriteSet() *kvrwset.KVRWSet
ToProto() *rwset.NsReadWriteSet
}
type NamespaceReadWriteSetImpl struct {
nsReadWriteSet *rwset.NsReadWriteSet
}
func ParseNamespaceReadWriteSet(nsRwSet *rwset.NsReadWriteSet) *NamespaceReadWriteSetImpl {
return &NamespaceReadWriteSetImpl{nsRwSet}
}
func (p *NamespaceReadWriteSetImpl) Namespace() string {
return p.nsReadWriteSet.GetNamespace()
}
func (p *NamespaceReadWriteSetImpl) ReadWriteSet() *kvrwset.KVRWSet {
return utils.Cache(func() *kvrwset.KVRWSet {
result := kvrwset.KVRWSet{}
if err := proto.Unmarshal(p.nsReadWriteSet.GetRwset(), &result); err != nil {
panic(err)
}
return &result
})()
}
// TODO remove unused
func (p *NamespaceReadWriteSetImpl) ToProto() *rwset.NsReadWriteSet {
return p.nsReadWriteSet
}

View file

@ -1,165 +1,30 @@
package parser package parser
import ( import (
"offChainData/utils"
"github.com/hyperledger/fabric-gateway/pkg/identity"
"github.com/hyperledger/fabric-protos-go-apiv2/common" "github.com/hyperledger/fabric-protos-go-apiv2/common"
"github.com/hyperledger/fabric-protos-go-apiv2/ledger/rwset"
"github.com/hyperledger/fabric-protos-go-apiv2/msp"
"github.com/hyperledger/fabric-protos-go-apiv2/peer"
"google.golang.org/protobuf/proto"
) )
type Transaction struct { type Transaction struct {
payload Payload payload *payload
} }
func NewTransaction(payload Payload) *Transaction { func newTransaction(payload *payload) *Transaction {
return &Transaction{payload} return &Transaction{payload}
} }
func (t *Transaction) ChannelHeader() *common.ChannelHeader { func (t *Transaction) ChannelHeader() *common.ChannelHeader {
return t.payload.ChannelHeader() return t.payload.channelHeader()
} }
// TODO remove unused? func (t *Transaction) NamespaceReadWriteSets() []*NamespaceReadWriteSet {
func (t *Transaction) Creator() identity.Identity { result := []*NamespaceReadWriteSet{}
creator := &msp.SerializedIdentity{} for _, readWriteSet := range t.payload.endorserTransaction().readWriteSets() {
if err := proto.Unmarshal(t.payload.SignatureHeader().GetCreator(), creator); err != nil { result = append(result, readWriteSet.namespaceReadWriteSets()...)
panic(err)
}
return &identityImpl{creator}
}
func (t *Transaction) NamespaceReadWriteSets() []NamespaceReadWriteSet {
result := []NamespaceReadWriteSet{}
for _, readWriteSet := range t.payload.EndorserTransaction().ReadWriteSets() {
result = append(result, readWriteSet.NamespaceReadWriteSets()...)
} }
return result return result
} }
// TODO remove unused?
func (t *Transaction) ValidationCode() int32 {
return t.payload.TransactionValidationCode()
}
// TODO remove unused?
func (t *Transaction) IsValid() bool { func (t *Transaction) IsValid() bool {
return t.payload.IsValid() return t.payload.isValid()
}
// TODO remove unused?
func (t *Transaction) ToProto() *common.Payload {
return t.payload.ToProto()
}
// TODO remove interface, use struct; encapsulate; extract into file
type EndorserTransaction interface {
ReadWriteSets() []ReadWriteSet
ToProto() *peer.Transaction
}
type EndorserTransactionImpl struct {
transaction *peer.Transaction
}
func ParseEndorserTransaction(transaction *peer.Transaction) *EndorserTransactionImpl {
return &EndorserTransactionImpl{transaction}
}
func (p *EndorserTransactionImpl) ReadWriteSets() []ReadWriteSet {
return utils.Cache(func() []ReadWriteSet {
chaincodeActionPayloads := p.unmarshalChaincodeActionPayloads()
chaincodeEndorsedActions := p.extractChaincodeEndorsedActionsFrom(chaincodeActionPayloads)
proposalResponsePayloads := p.unmarshalProposalResponsePayloadsFrom(chaincodeEndorsedActions)
chaincodeActions := p.unmarshalChaincodeActionsFrom(proposalResponsePayloads)
txReadWriteSets := p.unmarshalTxReadWriteSetsFrom(chaincodeActions)
return p.parseReadWriteSets(txReadWriteSets)
})()
}
func (p *EndorserTransactionImpl) unmarshalChaincodeActionPayloads() []*peer.ChaincodeActionPayload {
result := []*peer.ChaincodeActionPayload{}
for _, transactionAction := range p.transaction.GetActions() {
chaincodeActionPayload := &peer.ChaincodeActionPayload{}
if err := proto.Unmarshal(transactionAction.GetPayload(), chaincodeActionPayload); err != nil {
panic(err)
}
result = append(result, chaincodeActionPayload)
}
return result
}
func (*EndorserTransactionImpl) extractChaincodeEndorsedActionsFrom(chaincodeActionPayloads []*peer.ChaincodeActionPayload) []*peer.ChaincodeEndorsedAction {
result := []*peer.ChaincodeEndorsedAction{}
for _, payload := range chaincodeActionPayloads {
result = append(
result,
utils.AssertDefined(
payload.GetAction(),
"missing chaincode endorsed action",
),
)
}
return result
}
func (*EndorserTransactionImpl) unmarshalProposalResponsePayloadsFrom(chaincodeEndorsedActions []*peer.ChaincodeEndorsedAction) []*peer.ProposalResponsePayload {
result := []*peer.ProposalResponsePayload{}
for _, endorsedAction := range chaincodeEndorsedActions {
proposalResponsePayload := &peer.ProposalResponsePayload{}
if err := proto.Unmarshal(endorsedAction.GetProposalResponsePayload(), proposalResponsePayload); err != nil {
panic(err)
}
result = append(result, proposalResponsePayload)
}
return result
}
func (*EndorserTransactionImpl) unmarshalChaincodeActionsFrom(proposalResponsePayloads []*peer.ProposalResponsePayload) []*peer.ChaincodeAction {
result := []*peer.ChaincodeAction{}
for _, proposalResponsePayload := range proposalResponsePayloads {
chaincodeAction := &peer.ChaincodeAction{}
if err := proto.Unmarshal(proposalResponsePayload.GetExtension(), chaincodeAction); err != nil {
panic(err)
}
result = append(result, chaincodeAction)
}
return result
}
func (*EndorserTransactionImpl) unmarshalTxReadWriteSetsFrom(chaincodeActions []*peer.ChaincodeAction) []*rwset.TxReadWriteSet {
result := []*rwset.TxReadWriteSet{}
for _, chaincodeAction := range chaincodeActions {
txReadWriteSet := &rwset.TxReadWriteSet{}
if err := proto.Unmarshal(chaincodeAction.GetResults(), txReadWriteSet); err != nil {
continue
}
result = append(result, txReadWriteSet)
}
return result
}
func (*EndorserTransactionImpl) parseReadWriteSets(txReadWriteSets []*rwset.TxReadWriteSet) []ReadWriteSet {
result := []ReadWriteSet{}
for _, txReadWriteSet := range txReadWriteSets {
parsedReadWriteSet := ParseReadWriteSet(txReadWriteSet)
result = append(result, parsedReadWriteSet)
}
return result
}
// TODO remove unused
func (p *EndorserTransactionImpl) ToProto() *peer.Transaction {
return p.transaction
} }

View file

@ -9,20 +9,20 @@ import (
) )
type block struct { type block struct {
block *parser.Block parsedBlock *parser.Block
checkpointer *client.FileCheckpointer checkpointer *client.FileCheckpointer
writeToStore store.Writer writeToStore store.Writer
channelName string channelName string
} }
func NewBlock( func NewBlock(
_block *parser.Block, parsedBlock *parser.Block,
checkpointer *client.FileCheckpointer, checkpointer *client.FileCheckpointer,
writeToStore store.Writer, writeToStore store.Writer,
channelName string, channelName string,
) *block { ) *block {
return &block{ return &block{
_block, parsedBlock,
checkpointer, checkpointer,
writeToStore, writeToStore,
channelName, channelName,
@ -30,25 +30,25 @@ func NewBlock(
} }
func (b *block) Process() { func (b *block) Process() {
blockNumber := b.block.Number() blockNumber := b.parsedBlock.Number()
fmt.Println("\nReceived block", blockNumber) fmt.Println("\nReceived block", blockNumber)
for _, transaction := range b.validTransactions() { for _, validTransaction := range b.validTransactions() {
aTransactionProcessor := transactionProcessor{ aTransaction := transaction{
blockNumber, blockNumber,
transaction, validTransaction,
// TODO use pointer to parent and get blockNumber, store and channelName from parent // TODO use pointer to parent and get blockNumber, store and channelName from parent
b.writeToStore, b.writeToStore,
b.channelName, b.channelName,
} }
aTransactionProcessor.process() aTransaction.process()
transactionId := transaction.ChannelHeader().GetTxId() transactionId := validTransaction.ChannelHeader().GetTxId()
b.checkpointer.CheckpointTransaction(blockNumber, transactionId) b.checkpointer.CheckpointTransaction(blockNumber, transactionId)
} }
b.checkpointer.CheckpointBlock(b.block.Number()) b.checkpointer.CheckpointBlock(b.parsedBlock.Number())
} }
func (b *block) validTransactions() []*parser.Transaction { func (b *block) validTransactions() []*parser.Transaction {
@ -62,7 +62,7 @@ func (b *block) validTransactions() []*parser.Transaction {
} }
func (b *block) getNewTransactions() []*parser.Transaction { func (b *block) getNewTransactions() []*parser.Transaction {
transactions := b.block.Transactions() transactions := b.parsedBlock.Transactions()
lastTransactionId := b.checkpointer.TransactionID() lastTransactionId := b.checkpointer.TransactionID()
if lastTransactionId == "" { if lastTransactionId == "" {
@ -77,7 +77,7 @@ func (b *block) getNewTransactions() []*parser.Transaction {
func (b *block) findLastProcessedIndex() int { func (b *block) findLastProcessedIndex() int {
blockTransactionIds := []string{} blockTransactionIds := []string{}
for _, transaction := range b.block.Transactions() { for _, transaction := range b.parsedBlock.Transactions() {
blockTransactionIds = append(blockTransactionIds, transaction.ChannelHeader().GetTxId()) blockTransactionIds = append(blockTransactionIds, transaction.ChannelHeader().GetTxId())
} }
@ -93,7 +93,7 @@ func (b *block) findLastProcessedIndex() int {
fmt.Errorf( fmt.Errorf(
"checkpoint transaction ID %s not found in block %d containing transactions: %s", "checkpoint transaction ID %s not found in block %d containing transactions: %s",
lastTransactionId, lastTransactionId,
b.block.Number(), b.parsedBlock.Number(),
b.joinByComma(blockTransactionIds), b.joinByComma(blockTransactionIds),
), ),
) )

View file

@ -7,14 +7,14 @@ import (
"slices" "slices"
) )
type transactionProcessor struct { type transaction struct {
blockNumber uint64 blockNumber uint64
transaction *parser.Transaction transaction *parser.Transaction
writeToStore store.Writer writeToStore store.Writer
channelName string channelName string
} }
func (t *transactionProcessor) process() { func (t *transaction) process() {
transactionId := t.transaction.ChannelHeader().GetTxId() transactionId := t.transaction.ChannelHeader().GetTxId()
writes := t.writes() writes := t.writes()
@ -32,10 +32,12 @@ func (t *transactionProcessor) process() {
}) })
} }
func (t *transactionProcessor) writes() []store.Write { func (t *transaction) writes() []store.Write {
// TODO this entire code should live in the parser and just return the kvWrite which
// we then map to store.Write and return
t.channelName = t.transaction.ChannelHeader().GetChannelId() t.channelName = t.transaction.ChannelHeader().GetChannelId()
nonSystemCCReadWriteSets := []parser.NamespaceReadWriteSet{} nonSystemCCReadWriteSets := []*parser.NamespaceReadWriteSet{}
for _, nsReadWriteSet := range t.transaction.NamespaceReadWriteSets() { for _, nsReadWriteSet := range t.transaction.NamespaceReadWriteSets() {
if !t.isSystemChaincode(nsReadWriteSet.Namespace()) { if !t.isSystemChaincode(nsReadWriteSet.Namespace()) {
nonSystemCCReadWriteSets = append(nonSystemCCReadWriteSets, nsReadWriteSet) nonSystemCCReadWriteSets = append(nonSystemCCReadWriteSets, nsReadWriteSet)
@ -60,7 +62,7 @@ func (t *transactionProcessor) writes() []store.Write {
return writes return writes
} }
func (t *transactionProcessor) isSystemChaincode(chaincodeName string) bool { func (t *transaction) isSystemChaincode(chaincodeName string) bool {
systemChaincodeNames := []string{ systemChaincodeNames := []string{
"_lifecycle", "_lifecycle",
"cscc", "cscc",

View file

@ -27,7 +27,7 @@ func transact(clientConnection *grpc.ClientConn) {
type transactApp struct { type transactApp struct {
smartContract *atb.AssetTransferBasic smartContract *atb.AssetTransferBasic
batchSize uint batchSize int
} }
func newTransactApp(smartContract *atb.AssetTransferBasic) *transactApp { func newTransactApp(smartContract *atb.AssetTransferBasic) *transactApp {
@ -35,7 +35,7 @@ func newTransactApp(smartContract *atb.AssetTransferBasic) *transactApp {
} }
func (t *transactApp) run() { func (t *transactApp) run() {
for i := 0; i < int(t.batchSize); i++ { for i := 0; i < t.batchSize; i++ {
t.transact() t.transact()
} }
} }