Skip to content

Commit

Permalink
BFT Block Puller: seek content type header+sig to send full config bl…
Browse files Browse the repository at this point in the history
…ocks (#4393)

Signed-off-by: May Rosenbaum <mayro1595@gmail.com>
  • Loading branch information
MayRosenbaum authored Aug 27, 2023
1 parent dd9a0e4 commit 9677344
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 2 deletions.
2 changes: 1 addition & 1 deletion common/deliver/deliver.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ func (h *Handler) deliverBlocks(ctx context.Context, srv *Server, envelope *cb.E

logger.Debugf("[channel: %s] Delivering block [%d] for (%p) for %s", chdr.ChannelId, block.Header.Number, seekInfo, addr)

if seekInfo.ContentType == ab.SeekInfo_HEADER_WITH_SIG {
if seekInfo.ContentType == ab.SeekInfo_HEADER_WITH_SIG && !protoutil.IsConfigBlock(block) {
block.Data = nil
}

Expand Down
67 changes: 67 additions & 0 deletions common/deliver/deliver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,73 @@ var _ = Describe("Deliver", func() {
})
})

Context("when seek info is configured to header with sig content type and block can be a config block", func() {
BeforeEach(func() {
seekInfo = &ab.SeekInfo{
Start: &ab.SeekPosition{},
Stop: seekNewest,
ContentType: ab.SeekInfo_HEADER_WITH_SIG,
}
fakeBlockReader.HeightReturns(4)
fakeBlockIterator.NextStub = func() (*cb.Block, cb.Status) {
nxtCallCount := fakeBlockIterator.NextCallCount()
block := &cb.Block{
Header: &cb.BlockHeader{Number: uint64(nxtCallCount)},
Metadata: &cb.BlockMetadata{Metadata: [][]byte{{3}, {4}}},
}
if nxtCallCount == 1 || nxtCallCount == 3 {
block.Data = &cb.BlockData{Data: [][]byte{{1}, {2}}}
} else {
channelHeader = protoutil.MakeChannelHeader(cb.HeaderType_CONFIG, int32(1), "chain-1", 0)
payloadSignatureHeader := protoutil.MakeSignatureHeader(nil, make([]byte, 24))
protoutil.SetTxID(channelHeader, payloadSignatureHeader)
payloadHeader := protoutil.MakePayloadHeader(channelHeader, payloadSignatureHeader)
cg := protoutil.NewConfigGroup()
payload := &cb.Payload{Header: payloadHeader, Data: protoutil.MarshalOrPanic(&cb.ConfigEnvelope{Config: &cb.Config{ChannelGroup: cg}})}
envelope := &cb.Envelope{Payload: protoutil.MarshalOrPanic(payload), Signature: nil}

block.Data = &cb.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(envelope)}}
block.Header.DataHash = nil
}
return block, cb.Status_SUCCESS
}
})

It("sends blocks with non nil Data", func() {
err := handler.Handle(context.Background(), server)
Expect(err).NotTo(HaveOccurred())
Expect(fakeBlockReader.IteratorCallCount()).To(Equal(1))
start := fakeBlockReader.IteratorArgsForCall(0)
Expect(start).To(Equal(&ab.SeekPosition{}))
Expect(fakeBlockIterator.NextCallCount()).To(Equal(3))
Expect(fakeResponseSender.SendBlockResponseCallCount()).To(Equal(3))
for i := 0; i < fakeResponseSender.SendBlockResponseCallCount(); i++ {
b, _, _, _ := fakeResponseSender.SendBlockResponseArgsForCall(i)
if i+1 == 1 || i+1 == 3 {
Expect(b).To(Equal(&cb.Block{
Header: &cb.BlockHeader{Number: uint64(i + 1)},
Data: nil,
Metadata: &cb.BlockMetadata{Metadata: [][]byte{{3}, {4}}},
}))
} else {
payloadSignatureHeader := protoutil.MakeSignatureHeader(nil, make([]byte, 24))
protoutil.SetTxID(channelHeader, payloadSignatureHeader)
payloadHeader := protoutil.MakePayloadHeader(channelHeader, payloadSignatureHeader)
cg := protoutil.NewConfigGroup()
payload := &cb.Payload{Header: payloadHeader, Data: protoutil.MarshalOrPanic(&cb.ConfigEnvelope{Config: &cb.Config{ChannelGroup: cg}})}
envelope := &cb.Envelope{Payload: protoutil.MarshalOrPanic(payload), Signature: nil}
blk := &cb.Block{
Header: &cb.BlockHeader{Number: uint64(i + 1)},
Data: &cb.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(envelope)}},
Metadata: &cb.BlockMetadata{Metadata: [][]byte{{3}, {4}}},
}
Expect(b).To(Equal(blk))
Expect(b.Data.Data).NotTo(BeNil())
}
}
})
})

Context("when filtered blocks are requested", func() {
var fakeResponseSender *mock.FilteredResponseSender

Expand Down
11 changes: 10 additions & 1 deletion protoutil/commonutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,16 @@ func SignOrPanic(signer identity.Signer, msg []byte) []byte {
// IsConfigBlock validates whenever given block contains configuration
// update transaction
func IsConfigBlock(block *cb.Block) bool {
envelope, err := ExtractEnvelope(block, 0)
if block.Data == nil {
return false
}

if len(block.Data.Data) != 1 {
return false
}

marshaledEnvelope := block.Data.Data[0]
envelope, err := GetEnvelopeFromBlock(marshaledEnvelope)
if err != nil {
return false
}
Expand Down
16 changes: 16 additions & 0 deletions protoutil/commonutils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,22 @@ func TestIsConfigBlock(t *testing.T) {

result = IsConfigBlock(block)
require.False(t, result, "IsConfigBlock returns false for blocks with MESSAGE envelope")

// scenario 4: Data with more than one tx
result = IsConfigBlock(&cb.Block{
Header: nil,
Data: &cb.BlockData{Data: [][]byte{{1, 2, 3, 4}, {1, 2, 3, 4}}},
Metadata: nil,
})
require.False(t, result, "IsConfigBlock returns false for blocks with more than one transaction")

// scenario 5: nil data
result = IsConfigBlock(&cb.Block{
Header: nil,
Data: nil,
Metadata: nil,
})
require.False(t, result, "IsConfigBlock returns false for blocks with no data")
}

func TestEnvelopeToConfigUpdate(t *testing.T) {
Expand Down

0 comments on commit 9677344

Please sign in to comment.