Skip to content

Commit 312d7e1

Browse files
committed
[FAB-2688]: Verify blocks on delivery and during p2p
https://jira.hyperledger.org/browse/FAB-2688 Add block verification for delivery service client for blocks received from ordering service and verification for blocks transfered via state transfer mechanism. Change-Id: Icbfbd290a3488332fd9113df6cf31ff2c7598d67 Signed-off-by: Artem Barger <[email protected]>
1 parent ba1275c commit 312d7e1

File tree

10 files changed

+99
-18
lines changed

10 files changed

+99
-18
lines changed

core/deliverservice/blocksprovider/blocksprovider.go

+17-4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/hyperledger/fabric/gossip/discovery"
2626

2727
"github.com/hyperledger/fabric/common/localmsp"
28+
"github.com/hyperledger/fabric/gossip/api"
2829
"github.com/hyperledger/fabric/protos/common"
2930
gossip_proto "github.com/hyperledger/fabric/protos/gossip"
3031
"github.com/hyperledger/fabric/protos/orderer"
@@ -86,6 +87,8 @@ type blocksProviderImpl struct {
8687

8788
gossip GossipServiceAdapter
8889

90+
mcs api.MessageCryptoService
91+
8992
done int32
9093
}
9194

@@ -96,11 +99,12 @@ func init() {
9699
}
97100

98101
// NewBlocksProvider constructor function to creare blocks deliverer instance
99-
func NewBlocksProvider(chainID string, client BlocksDeliverer, gossip GossipServiceAdapter) BlocksProvider {
102+
func NewBlocksProvider(chainID string, client BlocksDeliverer, gossip GossipServiceAdapter, mcs api.MessageCryptoService) BlocksProvider {
100103
return &blocksProviderImpl{
101104
chainID: chainID,
102105
client: client,
103106
gossip: gossip,
107+
mcs: mcs,
104108
}
105109
}
106110

@@ -123,9 +127,19 @@ func (b *blocksProviderImpl) DeliverBlocks() {
123127
case *orderer.DeliverResponse_Block:
124128
seqNum := t.Block.Header.Number
125129

130+
marshaledBlock, err := proto.Marshal(t.Block)
131+
if err != nil {
132+
logger.Errorf("Error serializing block with sequence number %d, due to %s", seqNum, err)
133+
continue
134+
}
135+
if err := b.mcs.VerifyBlock(gossipcommon.ChainID(b.chainID), marshaledBlock); err != nil {
136+
logger.Errorf("Error verifying block with sequnce number %d, due to %s", seqNum, err)
137+
continue
138+
}
139+
126140
numberOfPeers := len(b.gossip.PeersOfChannel(gossipcommon.ChainID(b.chainID)))
127141
// Create payload with a block received
128-
payload := createPayload(seqNum, t.Block)
142+
payload := createPayload(seqNum, marshaledBlock)
129143
// Use payload to create gossip message
130144
gossipMsg := createGossipMsg(b.chainID, payload)
131145

@@ -223,8 +237,7 @@ func createGossipMsg(chainID string, payload *gossip_proto.Payload) *gossip_prot
223237
return gossipMsg
224238
}
225239

226-
func createPayload(seqNum uint64, block *common.Block) *gossip_proto.Payload {
227-
marshaledBlock, _ := proto.Marshal(block)
240+
func createPayload(seqNum uint64, marshaledBlock []byte) *gossip_proto.Payload {
228241
return &gossip_proto.Payload{
229242
Data: marshaledBlock,
230243
SeqNum: seqNum,

core/deliverservice/blocksprovider/blocksprovider_test.go

+30
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,40 @@ import (
2121
"time"
2222

2323
"github.com/hyperledger/fabric/core/deliverservice/mocks"
24+
"github.com/hyperledger/fabric/gossip/api"
25+
common2 "github.com/hyperledger/fabric/gossip/common"
2426
"github.com/hyperledger/fabric/protos/common"
2527
"github.com/hyperledger/fabric/protos/orderer"
2628
"github.com/stretchr/testify/assert"
2729
)
2830

31+
type mockMCS struct {
32+
}
33+
34+
func (*mockMCS) GetPKIidOfCert(peerIdentity api.PeerIdentityType) common2.PKIidType {
35+
return common2.PKIidType("pkiID")
36+
}
37+
38+
func (*mockMCS) VerifyBlock(chainID common2.ChainID, signedBlock []byte) error {
39+
return nil
40+
}
41+
42+
func (*mockMCS) Sign(msg []byte) ([]byte, error) {
43+
return msg, nil
44+
}
45+
46+
func (*mockMCS) Verify(peerIdentity api.PeerIdentityType, signature, message []byte) error {
47+
return nil
48+
}
49+
50+
func (*mockMCS) VerifyByChannel(chainID common2.ChainID, peerIdentity api.PeerIdentityType, signature, message []byte) error {
51+
return nil
52+
}
53+
54+
func (*mockMCS) ValidateIdentity(peerIdentity api.PeerIdentityType) error {
55+
return nil
56+
}
57+
2958
// Used to generate a simple test case to initialize delivery
3059
// from given block sequence number.
3160
func makeTestCase(ledgerHeight uint64) func(*testing.T) {
@@ -38,6 +67,7 @@ func makeTestCase(ledgerHeight uint64) func(*testing.T) {
3867
chainID: "***TEST_CHAINID***",
3968
gossip: gossipServiceAdapter,
4069
client: deliverer,
70+
mcs: &mockMCS{},
4171
}
4272

4373
provider.RequestBlocks(&mocks.MockLedgerInfo{ledgerHeight})

core/deliverservice/deliveryclient.go

+8-4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525

2626
"github.com/hyperledger/fabric/core/comm"
2727
"github.com/hyperledger/fabric/core/deliverservice/blocksprovider"
28+
"github.com/hyperledger/fabric/gossip/api"
2829
"github.com/hyperledger/fabric/protos/orderer"
2930
"github.com/op/go-logging"
3031
"golang.org/x/net/context"
@@ -95,13 +96,15 @@ type deliverServiceImpl struct {
9596
stopping bool
9697

9798
conn *grpc.ClientConn
99+
100+
mcs api.MessageCryptoService
98101
}
99102

100103
// NewDeliverService construction function to create and initialize
101104
// delivery service instance. It tries to establish connection to
102105
// the specified in the configuration ordering service, in case it
103106
// fails to dial to it, return nil
104-
func NewDeliverService(gossip blocksprovider.GossipServiceAdapter, endpoints []string) (DeliverService, error) {
107+
func NewDeliverService(gossip blocksprovider.GossipServiceAdapter, endpoints []string, mcs api.MessageCryptoService) (DeliverService, error) {
105108
indices := rand.Perm(len(endpoints))
106109
for _, idx := range indices {
107110
logger.Infof("Creating delivery service to get blocks from the ordering service, %s", endpoints[idx])
@@ -119,20 +122,21 @@ func NewDeliverService(gossip blocksprovider.GossipServiceAdapter, endpoints []s
119122
logger.Errorf("Cannot dial to %s, because of %s", endpoints[idx], err)
120123
continue
121124
}
122-
return NewFactoryDeliverService(gossip, &blocksDelivererFactoryImpl{conn}, conn), nil
125+
return NewFactoryDeliverService(gossip, &blocksDelivererFactoryImpl{conn}, conn, mcs), nil
123126
}
124127
return nil, fmt.Errorf("Wasn't able to connect to any of ordering service endpoints %s", endpoints)
125128
}
126129

127130
// NewFactoryDeliverService construction function to create and initialize
128131
// delivery service instance, with gossip service adapter and customized
129132
// factory to create blocks deliverers.
130-
func NewFactoryDeliverService(gossip blocksprovider.GossipServiceAdapter, factory BlocksDelivererFactory, conn *grpc.ClientConn) DeliverService {
133+
func NewFactoryDeliverService(gossip blocksprovider.GossipServiceAdapter, factory BlocksDelivererFactory, conn *grpc.ClientConn, mcs api.MessageCryptoService) DeliverService {
131134
return &deliverServiceImpl{
132135
clientsFactory: factory,
133136
gossip: gossip,
134137
clients: make(map[string]blocksprovider.BlocksProvider),
135138
conn: conn,
139+
mcs: mcs,
136140
}
137141
}
138142

@@ -159,7 +163,7 @@ func (d *deliverServiceImpl) StartDeliverForChannel(chainID string, ledgerInfo b
159163
return err
160164
}
161165
logger.Debug("This peer will pass blocks from orderer service to other peers")
162-
d.clients[chainID] = blocksprovider.NewBlocksProvider(chainID, abc, d.gossip)
166+
d.clients[chainID] = blocksprovider.NewBlocksProvider(chainID, abc, d.gossip, d.mcs)
163167

164168
if err := d.clients[chainID].RequestBlocks(ledgerInfo); err == nil {
165169
// Start reading blocks from ordering service in case this peer is a leader for specified chain

core/deliverservice/deliveryclient_test.go

+30-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import (
2424
"github.com/docker/docker/pkg/testutil/assert"
2525
"github.com/hyperledger/fabric/core/deliverservice/blocksprovider"
2626
"github.com/hyperledger/fabric/core/deliverservice/mocks"
27+
"github.com/hyperledger/fabric/gossip/api"
28+
"github.com/hyperledger/fabric/gossip/common"
2729
"github.com/spf13/viper"
2830
)
2931

@@ -35,6 +37,33 @@ func (mock *mockBlocksDelivererFactory) Create() (blocksprovider.BlocksDeliverer
3537
return mock.mockCreate()
3638
}
3739

40+
type mockMCS struct {
41+
}
42+
43+
func (*mockMCS) GetPKIidOfCert(peerIdentity api.PeerIdentityType) common.PKIidType {
44+
return common.PKIidType("pkiID")
45+
}
46+
47+
func (*mockMCS) VerifyBlock(chainID common.ChainID, signedBlock []byte) error {
48+
return nil
49+
}
50+
51+
func (*mockMCS) Sign(msg []byte) ([]byte, error) {
52+
return msg, nil
53+
}
54+
55+
func (*mockMCS) Verify(peerIdentity api.PeerIdentityType, signature, message []byte) error {
56+
return nil
57+
}
58+
59+
func (*mockMCS) VerifyByChannel(chainID common.ChainID, peerIdentity api.PeerIdentityType, signature, message []byte) error {
60+
return nil
61+
}
62+
63+
func (*mockMCS) ValidateIdentity(peerIdentity api.PeerIdentityType) error {
64+
return nil
65+
}
66+
3867
func TestNewDeliverService(t *testing.T) {
3968
viper.Set("peer.gossip.orgLeader", true)
4069

@@ -48,7 +77,7 @@ func TestNewDeliverService(t *testing.T) {
4877
return blocksDeliverer, nil
4978
}
5079

51-
service := NewFactoryDeliverService(gossipServiceAdapter, factory, nil)
80+
service := NewFactoryDeliverService(gossipServiceAdapter, factory, nil, &mockMCS{})
5281
assert.NilError(t, service.StartDeliverForChannel("TEST_CHAINID", &mocks.MockLedgerInfo{0}))
5382

5483
// Lets start deliver twice

core/peer/peer_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/hyperledger/fabric/core/deliverservice"
2929
"github.com/hyperledger/fabric/core/deliverservice/blocksprovider"
3030
"github.com/hyperledger/fabric/core/mocks/ccprovider"
31+
"github.com/hyperledger/fabric/gossip/api"
3132
"github.com/hyperledger/fabric/gossip/service"
3233
"github.com/hyperledger/fabric/msp/mgmt"
3334
"github.com/hyperledger/fabric/msp/mgmt/testtools"
@@ -60,7 +61,7 @@ func (*mockDeliveryClient) Stop() {
6061
type mockDeliveryClientFactory struct {
6162
}
6263

63-
func (*mockDeliveryClientFactory) Service(g service.GossipService, endpoints []string) (deliverclient.DeliverService, error) {
64+
func (*mockDeliveryClientFactory) Service(g service.GossipService, endpoints []string, mcs api.MessageCryptoService) (deliverclient.DeliverService, error) {
6465
return &mockDeliveryClient{}, nil
6566
}
6667

core/scc/cscc/configure_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"github.com/hyperledger/fabric/core/deliverservice/blocksprovider"
3232
"github.com/hyperledger/fabric/core/ledger/ledgermgmt"
3333
"github.com/hyperledger/fabric/core/peer"
34+
"github.com/hyperledger/fabric/gossip/api"
3435
"github.com/hyperledger/fabric/gossip/service"
3536
"github.com/hyperledger/fabric/msp/mgmt"
3637
"github.com/hyperledger/fabric/msp/mgmt/testtools"
@@ -66,7 +67,7 @@ func (*mockDeliveryClient) Stop() {
6667
type mockDeliveryClientFactory struct {
6768
}
6869

69-
func (*mockDeliveryClientFactory) Service(g service.GossipService, endpoints []string) (deliverclient.DeliverService, error) {
70+
func (*mockDeliveryClientFactory) Service(g service.GossipService, endpoints []string, mcs api.MessageCryptoService) (deliverclient.DeliverService, error) {
7071
return &mockDeliveryClient{}, nil
7172
}
7273

gossip/election/election_test.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,12 @@ package election
1818

1919
import (
2020
"fmt"
21+
"strings"
2122
"sync"
2223
"sync/atomic"
2324
"testing"
2425
"time"
2526

26-
"strings"
27-
2827
"github.com/spf13/viper"
2928
"github.com/stretchr/testify/assert"
3029
"github.com/stretchr/testify/mock"

gossip/service/gossip_service.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,15 @@ type GossipService interface {
6161
// DeliveryServiceFactory factory to create and initialize delivery service instance
6262
type DeliveryServiceFactory interface {
6363
// Returns an instance of delivery client
64-
Service(g GossipService, endpoints []string) (deliverclient.DeliverService, error)
64+
Service(g GossipService, endpoints []string, msc api.MessageCryptoService) (deliverclient.DeliverService, error)
6565
}
6666

6767
type deliveryFactoryImpl struct {
6868
}
6969

7070
// Returns an instance of delivery client
71-
func (*deliveryFactoryImpl) Service(g GossipService, endpoints []string) (deliverclient.DeliverService, error) {
72-
return deliverclient.NewDeliverService(g, endpoints)
71+
func (*deliveryFactoryImpl) Service(g GossipService, endpoints []string, mcs api.MessageCryptoService) (deliverclient.DeliverService, error) {
72+
return deliverclient.NewDeliverService(g, endpoints, mcs)
7373
}
7474

7575
type gossipServiceImpl struct {
@@ -168,7 +168,7 @@ func (g *gossipServiceImpl) InitializeChannel(chainID string, committer committe
168168
g.chains[chainID] = state.NewGossipStateProvider(chainID, g, committer, g.mcs)
169169
if g.deliveryService == nil {
170170
var err error
171-
g.deliveryService, err = g.deliveryFactory.Service(gossipServiceInstance, endpoints)
171+
g.deliveryService, err = g.deliveryFactory.Service(gossipServiceInstance, endpoints, g.mcs)
172172
if err != nil {
173173
logger.Warning("Cannot create delivery client, due to", err)
174174
}

gossip/service/gossip_service_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ type mockDeliverServiceFactory struct {
270270
service *mockDeliverService
271271
}
272272

273-
func (mf *mockDeliverServiceFactory) Service(g GossipService, endpoints []string) (deliverclient.DeliverService, error) {
273+
func (mf *mockDeliverServiceFactory) Service(g GossipService, endpoints []string, mcs api.MessageCryptoService) (deliverclient.DeliverService, error) {
274274
return mf.service, nil
275275
}
276276

gossip/state/state.go

+4
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,10 @@ func (s *GossipStateProviderImpl) handleStateResponse(msg proto.ReceivedMessage)
266266
response := msg.GetGossipMessage().GetStateResponse()
267267
for _, payload := range response.GetPayloads() {
268268
s.logger.Debugf("Received payload with sequence number %d.", payload.SeqNum)
269+
if err := s.mcs.VerifyBlock(common2.ChainID(s.chainID), payload.Data); err != nil {
270+
s.logger.Warningf("Error verifying block with sequence number %d, due to %s", payload.SeqNum, err)
271+
return
272+
}
269273
err := s.payloads.Push(payload)
270274
if err != nil {
271275
s.logger.Warningf("Payload with sequence number %d was received earlier", payload.SeqNum)

0 commit comments

Comments
 (0)