Skip to content

Commit 1bf6190

Browse files
author
Jason Yellick
committed
[FAB-1573] Make deliver API signable
https://jira.hyperledger.org/browse/FAB-1573 This changeset modifies the Deliver API to accept an Envelope of type DELIVER_SEEK_INFO instead of a standard SeekInfo message. The Envelope embeds a SeekInfo as well as the bits necessary to construct a non-replayable signature. This unfortunately breaks the API, but it seems better to fix it now than to wait until there are more dependencies. The alternative was to invent yet another signing scheme, which seemed like it would be equally as much work on the consumer side with ongoing messiness. Change-Id: I3e8a759d33f68cb6a69f5242440136da730f0396 Signed-off-by: Jason Yellick <[email protected]>
1 parent 149ae0d commit 1bf6190

File tree

14 files changed

+291
-195
lines changed

14 files changed

+291
-195
lines changed

bddtests/orderer/ab_pb2.py

+19-26
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bddtests/orderer/ab_pb2_grpc.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import common.common_pb2 as common_dot_common__pb2
66
import orderer.ab_pb2 as orderer_dot_ab__pb2
7-
import orderer.ab_pb2 as orderer_dot_ab__pb2
7+
import common.common_pb2 as common_dot_common__pb2
88
import orderer.ab_pb2 as orderer_dot_ab__pb2
99

1010

@@ -23,7 +23,7 @@ def __init__(self, channel):
2323
)
2424
self.Deliver = channel.stream_stream(
2525
'/orderer.AtomicBroadcast/Deliver',
26-
request_serializer=orderer_dot_ab__pb2.SeekInfo.SerializeToString,
26+
request_serializer=common_dot_common__pb2.Envelope.SerializeToString,
2727
response_deserializer=orderer_dot_ab__pb2.DeliverResponse.FromString,
2828
)
2929

@@ -38,7 +38,7 @@ def Broadcast(self, request_iterator, context):
3838
raise NotImplementedError('Method not implemented!')
3939

4040
def Deliver(self, request_iterator, context):
41-
"""deliver first requires an update containing a seek message, then a stream of block replies is received.
41+
"""deliver first requires an Envelope of type DELIVER_SEEK_INFO with Payload data as a mashaled SeekInfo message, then a stream of block replies is received.
4242
"""
4343
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
4444
context.set_details('Method not implemented!')
@@ -54,7 +54,7 @@ def add_AtomicBroadcastServicer_to_server(servicer, server):
5454
),
5555
'Deliver': grpc.stream_stream_rpc_method_handler(
5656
servicer.Deliver,
57-
request_deserializer=orderer_dot_ab__pb2.SeekInfo.FromString,
57+
request_deserializer=common_dot_common__pb2.Envelope.FromString,
5858
response_serializer=orderer_dot_ab__pb2.DeliverResponse.SerializeToString,
5959
),
6060
}

bddtests/steps/orderer_util.py

+12-5
Original file line numberDiff line numberDiff line change
@@ -210,11 +210,18 @@ def seekPosition(position):
210210
return ab_pb2.SeekPosition(specified = ab_pb2.SeekSpecified(number = position))
211211

212212
def createSeekInfo(chainID = TEST_CHAIN_ID, start = 'Oldest', end = 'Newest', behavior = 'FAIL_IF_NOT_READY'):
213-
return ab_pb2.SeekInfo(
214-
chainID = chainID,
215-
start = seekPosition(start),
216-
stop = seekPosition(end),
217-
behavior = ab_pb2.SeekInfo.SeekBehavior.Value(behavior),
213+
return common_pb2.Envelope(
214+
payload = common_pb2.Payload(
215+
header = common_pb2.Header(
216+
chainHeader = common_pb2.ChainHeader( chainID = chainID ),
217+
signatureHeader = common_pb2.SignatureHeader(),
218+
),
219+
data = ab_pb2.SeekInfo(
220+
start = seekPosition(start),
221+
stop = seekPosition(end),
222+
behavior = ab_pb2.SeekInfo.SeekBehavior.Value(behavior),
223+
).SerializeToString(),
224+
).SerializeToString(),
218225
)
219226

220227
def generateBroadcastMessages(chainID = TEST_CHAIN_ID, numToGenerate = 1, timeToHoldOpen = 1):

core/deliverservice/client.go

+29-10
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/hyperledger/fabric/gossip/service"
3131
"github.com/hyperledger/fabric/protos/common"
3232
"github.com/hyperledger/fabric/protos/orderer"
33+
"github.com/hyperledger/fabric/protos/utils"
3334
"github.com/op/go-logging"
3435
"github.com/spf13/viper"
3536
"golang.org/x/net/context"
@@ -155,20 +156,38 @@ func (d *DeliverService) checkLeaderAndRunDeliver(committer committer.Committer)
155156
}
156157

157158
func (d *DeliverService) seekOldest() error {
158-
return d.client.Send(&orderer.SeekInfo{
159-
ChainID: d.chainID,
160-
Start: &orderer.SeekPosition{Type: &orderer.SeekPosition_Oldest{Oldest: &orderer.SeekOldest{}}},
161-
Stop: &orderer.SeekPosition{Type: &orderer.SeekPosition_Specified{Specified: &orderer.SeekSpecified{Number: math.MaxUint64}}},
162-
Behavior: orderer.SeekInfo_BLOCK_UNTIL_READY,
159+
return d.client.Send(&common.Envelope{
160+
Payload: utils.MarshalOrPanic(&common.Payload{
161+
Header: &common.Header{
162+
ChainHeader: &common.ChainHeader{
163+
ChainID: d.chainID,
164+
},
165+
SignatureHeader: &common.SignatureHeader{},
166+
},
167+
Data: utils.MarshalOrPanic(&orderer.SeekInfo{
168+
Start: &orderer.SeekPosition{Type: &orderer.SeekPosition_Oldest{Oldest: &orderer.SeekOldest{}}},
169+
Stop: &orderer.SeekPosition{Type: &orderer.SeekPosition_Specified{Specified: &orderer.SeekSpecified{Number: math.MaxUint64}}},
170+
Behavior: orderer.SeekInfo_BLOCK_UNTIL_READY,
171+
}),
172+
}),
163173
})
164174
}
165175

166176
func (d *DeliverService) seekLatestFromCommitter(height uint64) error {
167-
return d.client.Send(&orderer.SeekInfo{
168-
ChainID: d.chainID,
169-
Start: &orderer.SeekPosition{Type: &orderer.SeekPosition_Specified{Specified: &orderer.SeekSpecified{Number: height}}},
170-
Stop: &orderer.SeekPosition{Type: &orderer.SeekPosition_Specified{Specified: &orderer.SeekSpecified{Number: math.MaxUint64}}},
171-
Behavior: orderer.SeekInfo_BLOCK_UNTIL_READY,
177+
return d.client.Send(&common.Envelope{
178+
Payload: utils.MarshalOrPanic(&common.Payload{
179+
Header: &common.Header{
180+
ChainHeader: &common.ChainHeader{
181+
ChainID: d.chainID,
182+
},
183+
SignatureHeader: &common.SignatureHeader{},
184+
},
185+
Data: utils.MarshalOrPanic(&orderer.SeekInfo{
186+
Start: &orderer.SeekPosition{Type: &orderer.SeekPosition_Specified{Specified: &orderer.SeekSpecified{Number: height}}},
187+
Stop: &orderer.SeekPosition{Type: &orderer.SeekPosition_Specified{Specified: &orderer.SeekSpecified{Number: math.MaxUint64}}},
188+
Behavior: orderer.SeekInfo_BLOCK_UNTIL_READY,
189+
}),
190+
}),
172191
})
173192
}
174193

orderer/common/deliver/deliver.go

+25-3
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@ limitations under the License.
1717
package deliver
1818

1919
import (
20+
"fmt"
21+
2022
"github.com/hyperledger/fabric/common/policies"
2123
"github.com/hyperledger/fabric/orderer/rawledger"
2224
cb "github.com/hyperledger/fabric/protos/common"
2325
ab "github.com/hyperledger/fabric/protos/orderer"
2426
"github.com/op/go-logging"
27+
28+
"github.com/golang/protobuf/proto"
2529
)
2630

2731
var logger = logging.MustGetLogger("orderer/common/deliver")
@@ -60,20 +64,38 @@ func (ds *deliverServer) Handle(srv ab.AtomicBroadcast_DeliverServer) error {
6064
logger.Debugf("Starting new deliver loop")
6165
for {
6266
logger.Debugf("Attempting to read seek info message")
63-
seekInfo, err := srv.Recv()
67+
envelope, err := srv.Recv()
6468
if err != nil {
6569
logger.Errorf("Error reading from stream: %s", err)
6670
return err
6771
}
68-
logger.Debugf("Received message %v", seekInfo)
72+
payload := &cb.Payload{}
73+
if err = proto.Unmarshal(envelope.Payload, payload); err != nil {
74+
logger.Errorf("Received an envelope with no payload: %s", err)
75+
return err
76+
}
6977

70-
chain, ok := ds.sm.GetChain(seekInfo.ChainID)
78+
if payload.Header == nil || payload.Header.ChainHeader == nil {
79+
err := fmt.Errorf("Malformed envelope recieved with bad header")
80+
logger.Error(err)
81+
return err
82+
}
83+
84+
chain, ok := ds.sm.GetChain(payload.Header.ChainHeader.ChainID)
7185
if !ok {
7286
return sendStatusReply(srv, cb.Status_NOT_FOUND)
7387
}
7488

7589
// XXX add deliver authorization checking
7690

91+
seekInfo := &ab.SeekInfo{}
92+
if err = proto.Unmarshal(payload.Data, seekInfo); err != nil {
93+
logger.Errorf("Received a signed deliver request with malformed seekInfo payload: %s", err)
94+
return err
95+
}
96+
97+
logger.Debugf("Received seekInfo %v", seekInfo)
98+
7799
cursor, number := chain.Reader().Iterator(seekInfo.Start)
78100
var stopNum uint64
79101
switch stop := seekInfo.Stop.Type.(type) {

0 commit comments

Comments
 (0)