peer.go 23.8 KB
Newer Older
1
/*
2
Copyright IBM Corp. All Rights Reserved.
3

4
SPDX-License-Identifier: Apache-2.0
5
6
7
8
9
*/

package peer

import (
10
	"fmt"
11
	"net"
12
	"runtime"
13
	"sync"
14

15
	"github.com/hyperledger/fabric/common/channelconfig"
16
	cc "github.com/hyperledger/fabric/common/config"
17
	"github.com/hyperledger/fabric/common/configtx"
18
	"github.com/hyperledger/fabric/common/deliver"
19
	"github.com/hyperledger/fabric/common/flogging"
20
21
	commonledger "github.com/hyperledger/fabric/common/ledger"
	"github.com/hyperledger/fabric/common/ledger/blockledger"
22
	fileledger "github.com/hyperledger/fabric/common/ledger/blockledger/file"
23
	"github.com/hyperledger/fabric/common/metrics"
24
	"github.com/hyperledger/fabric/common/policies"
25
	"github.com/hyperledger/fabric/core/chaincode/platforms"
26
	"github.com/hyperledger/fabric/core/comm"
27
	"github.com/hyperledger/fabric/core/committer"
28
	"github.com/hyperledger/fabric/core/committer/txvalidator"
29
	"github.com/hyperledger/fabric/core/common/ccprovider"
30
	"github.com/hyperledger/fabric/core/common/privdata"
31
	"github.com/hyperledger/fabric/core/common/sysccprovider"
32
	"github.com/hyperledger/fabric/core/ledger"
33
	"github.com/hyperledger/fabric/core/ledger/customtx"
34
	"github.com/hyperledger/fabric/core/ledger/ledgermgmt"
35
	"github.com/hyperledger/fabric/core/transientstore"
36
	"github.com/hyperledger/fabric/gossip/api"
37
	"github.com/hyperledger/fabric/gossip/service"
38
	"github.com/hyperledger/fabric/msp"
39
	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
40
	"github.com/hyperledger/fabric/protos/common"
41
	pb "github.com/hyperledger/fabric/protos/peer"
42
	"github.com/hyperledger/fabric/protos/utils"
43
44
	"github.com/hyperledger/fabric/token/tms/manager"
	"github.com/hyperledger/fabric/token/transaction"
45
	"github.com/pkg/errors"
46
	"github.com/spf13/viper"
47
	"golang.org/x/sync/semaphore"
48
49
)

50
var peerLogger = flogging.MustGetLogger("peer")
51

52
var peerServer *comm.GRPCServer
53

54
var configTxProcessor = newConfigTxProcessor()
55
56
57
var tokenTxProcessor = &transaction.Processor{
	TMSManager: &manager.Manager{
		IdentityDeserializerManager: &manager.FabricIdentityDeserializerManager{}}}
58
var ConfigTxProcessors = customtx.Processors{
59
60
	common.HeaderType_CONFIG:            configTxProcessor,
	common.HeaderType_TOKEN_TRANSACTION: tokenTxProcessor,
61
62
}

63
64
// singleton instance to manage credentials for the peer across channel config changes
var credSupport = comm.GetCredentialSupport()
65

66
67
type gossipSupport struct {
	channelconfig.Application
68
	configtx.Validator
69
	channelconfig.Channel
70
71
72
}

type chainSupport struct {
73
	bundleSource *channelconfig.BundleSource
74
75
	channelconfig.Resources
	channelconfig.Application
76
	ledger ledger.PeerLedger
77
78
}

79
var TransientStoreFactory = &storeProvider{stores: make(map[string]transientstore.Store)}
80
81

type storeProvider struct {
82
	stores map[string]transientstore.Store
83
	transientstore.StoreProvider
84
85
86
87
88
89
90
	sync.RWMutex
}

func (sp *storeProvider) StoreForChannel(channel string) transientstore.Store {
	sp.RLock()
	defer sp.RUnlock()
	return sp.stores[channel]
91
92
93
94
95
96
97
98
}

func (sp *storeProvider) OpenStore(ledgerID string) (transientstore.Store, error) {
	sp.Lock()
	defer sp.Unlock()
	if sp.StoreProvider == nil {
		sp.StoreProvider = transientstore.NewStoreProvider()
	}
99
100
101
102
103
	store, err := sp.StoreProvider.OpenStore(ledgerID)
	if err == nil {
		sp.stores[ledgerID] = store
	}
	return store, err
104
105
}

106
func (cs *chainSupport) Apply(configtx *common.ConfigEnvelope) error {
107
	err := cs.ConfigtxValidator().Validate(configtx)
108
109
110
111
112
113
	if err != nil {
		return err
	}

	// If the chainSupport is being mocked, this field will be nil
	if cs.bundleSource != nil {
114
		bundle, err := channelconfig.NewBundle(cs.ConfigtxValidator().ChainID(), configtx.Config)
115
116
117
		if err != nil {
			return err
		}
118
119
120

		channelconfig.LogSanityChecks(bundle)

121
		err = cs.bundleSource.ValidateNew(bundle)
122
123
124
		if err != nil {
			return err
		}
125
126
127

		capabilitiesSupportedOrPanic(bundle)

128
		cs.bundleSource.Update(bundle)
129
130
131
132
	}
	return nil
}

133
134
135
func capabilitiesSupportedOrPanic(res channelconfig.Resources) {
	ac, ok := res.ApplicationConfig()
	if !ok {
136
		peerLogger.Panicf("[channel %s] does not have application config so is incompatible", res.ConfigtxValidator().ChainID())
137
138
139
	}

	if err := ac.Capabilities().Supported(); err != nil {
140
		peerLogger.Panicf("[channel %s] incompatible: %s", res.ConfigtxValidator().ChainID(), err)
141
142
143
	}

	if err := res.ChannelConfig().Capabilities().Supported(); err != nil {
144
		peerLogger.Panicf("[channel %s] incompatible: %s", res.ConfigtxValidator().ChainID(), err)
145
146
147
	}
}

148
149
150
151
func (cs *chainSupport) Ledger() ledger.PeerLedger {
	return cs.ledger
}

152
153
154
155
func (cs *chainSupport) GetMSPIDs(cid string) []string {
	return GetMSPIDs(cid)
}

156
157
// Sequence passes through to the underlying configtx.Validator
func (cs *chainSupport) Sequence() uint64 {
158
	sb := cs.bundleSource.StableBundle()
159
	return sb.ConfigtxValidator().Sequence()
160
}
161
162

// Reader returns an iterator to read from the ledger
163
func (cs *chainSupport) Reader() blockledger.Reader {
164
	return fileledger.NewFileLedger(fileLedgerBlockStore{cs.ledger})
165
}
166
167
168
169
170

// Errored returns a channel that can be used to determine
// if a backing resource has errored. At this point in time,
// the peer does not have any error conditions that lead to
// this function signaling that an error has occurred.
171
func (cs *chainSupport) Errored() <-chan struct{} {
172
173
	// If this is ever updated to return a real channel, the error message
	// in deliver.go around this channel closing should be updated.
174
175
176
	return nil
}

177
178
// chain is a local struct to manage objects in a chain
type chain struct {
179
	cs        *chainSupport
180
181
	cb        *common.Block
	committer committer.Committer
182
183
}

184
185
186
187
188
189
// chains is a local map of chainID->chainObject
var chains = struct {
	sync.RWMutex
	list map[string]*chain
}{list: make(map[string]*chain)}

190
var chainInitializer func(string)
191

192
193
var pluginMapper txvalidator.PluginMapper

194
195
196
197
198
199
var mockMSPIDGetter func(string) []string

func MockSetMSPIDGetter(mspIDGetter func(string) []string) {
	mockMSPIDGetter = mspIDGetter
}

200
201
202
203
// validationWorkersSemaphore is the semaphore used to ensure that
// there are not too many concurrent tx validation goroutines
var validationWorkersSemaphore *semaphore.Weighted

204
205
206
// Initialize sets up any chains that the peer has from the persistence. This
// function should be called at the start up when the ledger and gossip
// ready
207
208
209
func Initialize(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider,
	pm txvalidator.PluginMapper, pr *platforms.Registry, deployedCCInfoProvider ledger.DeployedChaincodeInfoProvider,
	membershipProvider ledger.MembershipInfoProvider, metricsProvider metrics.Provider) {
210
211
212
213
214
215
	nWorkers := viper.GetInt("peer.validatorPoolSize")
	if nWorkers <= 0 {
		nWorkers = runtime.NumCPU()
	}
	validationWorkersSemaphore = semaphore.NewWeighted(int64(nWorkers))

216
	pluginMapper = pm
217
	chainInitializer = init
218

219
	var cb *common.Block
220
	var ledger ledger.PeerLedger
221
	ledgermgmt.Initialize(&ledgermgmt.Initializer{
222
223
224
		CustomTxProcessors:            ConfigTxProcessors,
		PlatformRegistry:              pr,
		DeployedChaincodeInfoProvider: deployedCCInfoProvider,
225
		MembershipInfoProvider:        membershipProvider,
226
		MetricsProvider:               metricsProvider,
227
	})
228
	ledgerIds, err := ledgermgmt.GetLedgerIDs()
229
	if err != nil {
230
		panic(fmt.Errorf("Error in initializing ledgermgmt: %s", err))
231
	}
232
	for _, cid := range ledgerIds {
233
		peerLogger.Infof("Loading chain %s", cid)
234
		if ledger, err = ledgermgmt.OpenLedger(cid); err != nil {
235
			peerLogger.Warningf("Failed to load ledger %s(%s)", cid, err)
236
			peerLogger.Debugf("Error while loading ledger %s with message %s. We continue to the next ledger rather than abort.", cid, err)
237
238
239
			continue
		}
		if cb, err = getCurrConfigBlockFromLedger(ledger); err != nil {
240
			peerLogger.Warningf("Failed to find config block on ledger %s(%s)", cid, err)
241
			peerLogger.Debugf("Error while looking for config block on ledger %s with message %s. We continue to the next ledger rather than abort.", cid, err)
242
243
244
			continue
		}
		// Create a chain if we get a valid ledger with config block
245
		if err = createChain(cid, ledger, cb, ccp, sccp, pm); err != nil {
246
			peerLogger.Warningf("Failed to load chain %s(%s)", cid, err)
247
			peerLogger.Debugf("Error reloading chain %s with message %s. We continue to the next chain rather than abort.", cid, err)
248
			continue
249
		}
250

251
		InitChain(cid)
252
253
254
	}
}

255
// InitChain takes care to initialize chain after peer joined, for example deploys system CCs
256
257
258
func InitChain(cid string) {
	if chainInitializer != nil {
		// Initialize chaincode, namely deploy system CC
259
		peerLogger.Debugf("Initializing channel %s", cid)
260
		chainInitializer(cid)
261
262
263
	}
}

264
func getCurrConfigBlockFromLedger(ledger ledger.PeerLedger) (*common.Block, error) {
265
266
267
268
269
270
	peerLogger.Debugf("Getting config block")

	// get last block.  Last block number is Height-1
	blockchainInfo, err := ledger.GetBlockchainInfo()
	if err != nil {
		return nil, err
271
	}
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
	lastBlock, err := ledger.GetBlockByNumber(blockchainInfo.Height - 1)
	if err != nil {
		return nil, err
	}

	// get most recent config block location from last block metadata
	configBlockIndex, err := utils.GetLastConfigIndexFromBlock(lastBlock)
	if err != nil {
		return nil, err
	}

	// get most recent config block
	configBlock, err := ledger.GetBlockByNumber(configBlockIndex)
	if err != nil {
		return nil, err
	}

	peerLogger.Debugf("Got config block[%d]", configBlockIndex)
	return configBlock, nil
291
292
293
}

// createChain creates a new chain object and insert it into the chains
294
func createChain(cid string, ledger ledger.PeerLedger, cb *common.Block, ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider, pm txvalidator.PluginMapper) error {
295
	chanConf, err := retrievePersistedChannelConfig(ledger)
296
297
298
299
	if err != nil {
		return err
	}

300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
	var bundle *channelconfig.Bundle

	if chanConf != nil {
		bundle, err = channelconfig.NewBundle(cid, chanConf)
		if err != nil {
			return err
		}
	} else {
		// Config was only stored in the statedb starting with v1.1 binaries
		// so if the config is not found there, extract it manually from the config block
		envelopeConfig, err := utils.ExtractEnvelope(cb, 0)
		if err != nil {
			return err
		}

		bundle, err = channelconfig.NewBundleFromEnvelope(envelopeConfig)
		if err != nil {
			return err
		}
319
320
	}

321
322
	capabilitiesSupportedOrPanic(bundle)

323
324
	channelconfig.LogSanityChecks(bundle)

325
326
	gossipEventer := service.GetGossipService().NewConfigEventer()

327
328
	gossipCallbackWrapper := func(bundle *channelconfig.Bundle) {
		ac, ok := bundle.ApplicationConfig()
329
330
331
332
		if !ok {
			// TODO, handle a missing ApplicationConfig more gracefully
			ac = nil
		}
333
		gossipEventer.ProcessConfigUpdate(&gossipSupport{
334
			Validator:   bundle.ConfigtxValidator(),
335
			Application: ac,
336
			Channel:     bundle.ChannelConfig(),
337
		})
338
339
340
341
342
343
344
		service.GetGossipService().SuspectPeers(func(identity api.PeerIdentityType) bool {
			// TODO: this is a place-holder that would somehow make the MSP layer suspect
			// that a given certificate is revoked, or its intermediate CA is revoked.
			// In the meantime, before we have such an ability, we return true in order
			// to suspect ALL identities in order to validate all of them.
			return true
		})
345
346
	}

347
348
	trustedRootsCallbackWrapper := func(bundle *channelconfig.Bundle) {
		updateTrustedRoots(bundle)
349
350
	}

351
	mspCallback := func(bundle *channelconfig.Bundle) {
352
		// TODO remove once all references to mspmgmt are gone from peer code
353
		mspmgmt.XXXSetMSPManager(cid, bundle.MSPManager())
354
355
	}

356
	ac, ok := bundle.ApplicationConfig()
357
358
359
	if !ok {
		ac = nil
	}
360

361
	cs := &chainSupport{
362
		Application: ac, // TODO, refactor as this is accessible through Manager
363
		ledger:      ledger,
364
365
	}

366
367
	peerSingletonCallback := func(bundle *channelconfig.Bundle) {
		ac, ok := bundle.ApplicationConfig()
368
369
370
371
		if !ok {
			ac = nil
		}
		cs.Application = ac
372
		cs.Resources = bundle
373
	}
374

375
376
	cs.bundleSource = channelconfig.NewBundleSource(
		bundle,
377
378
379
380
381
382
		gossipCallbackWrapper,
		trustedRootsCallbackWrapper,
		mspCallback,
		peerSingletonCallback,
	)

383
384
385
	vcs := struct {
		*chainSupport
		*semaphore.Weighted
386
	}{cs, validationWorkersSemaphore}
387
	validator := txvalidator.NewTxValidator(cid, vcs, sccp, pm)
388
	c := committer.NewLedgerCommitterReactive(ledger, func(block *common.Block) error {
389
390
391
392
393
394
395
		chainID, err := utils.GetChainIDFromBlock(block)
		if err != nil {
			return err
		}
		return SetCurrConfigBlock(block, chainID)
	})

396
	ordererAddresses := bundle.ChannelConfig().OrdererAddresses()
397
	if len(ordererAddresses) == 0 {
398
		return errors.New("no ordering service endpoint provided in configuration block")
399
	}
400

401
	// TODO: does someone need to call Close() on the transientStoreFactory at shutdown of the peer?
402
	store, err := TransientStoreFactory.OpenStore(bundle.ConfigtxValidator().ChainID())
403
	if err != nil {
404
		return errors.Wrapf(err, "[channel %s] failed opening transient store", bundle.ConfigtxValidator().ChainID())
405
	}
406
	csStoreSupport := &CollectionSupport{
407
		PeerLedger: ledger,
408
409
410
	}
	simpleCollectionStore := privdata.NewSimpleCollectionStore(csStoreSupport)

411
	service.GetGossipService().InitializeChannel(bundle.ConfigtxValidator().ChainID(), ordererAddresses, service.Support{
412
413
414
415
416
		Validator:            validator,
		Committer:            c,
		Store:                store,
		Cs:                   simpleCollectionStore,
		IdDeserializeFactory: csStoreSupport,
417
	})
418
419
420

	chains.Lock()
	defer chains.Unlock()
421
	chains.list[cid] = &chain{
422
		cs:        cs,
423
424
425
		cb:        cb,
		committer: c,
	}
426

427
428
429
430
	return nil
}

// CreateChainFromBlock creates a new chain from config block
431
func CreateChainFromBlock(cb *common.Block, ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider) error {
432
433
434
435
436
	cid, err := utils.GetChainIDFromBlock(cb)
	if err != nil {
		return err
	}

437
	var l ledger.PeerLedger
438
	if l, err = ledgermgmt.CreateLedger(cb); err != nil {
439
		return errors.WithMessage(err, "cannot create ledger from genesis block")
440
	}
441

442
	return createChain(cid, l, cb, ccp, sccp, pluginMapper)
443
444
445
446
}

// GetLedger returns the ledger of the chain with chain ID. Note that this
// call returns nil if chain cid has not been created.
447
func GetLedger(cid string) ledger.PeerLedger {
448
449
450
	chains.RLock()
	defer chains.RUnlock()
	if c, ok := chains.list[cid]; ok {
451
		return c.cs.ledger
452
453
454
455
	}
	return nil
}

456
457
458
459
460
461
// GetStableChannelConfig returns the stable channel configuration of the chain with channel ID.
// Note that this call returns nil if chain cid has not been created.
func GetStableChannelConfig(cid string) channelconfig.Resources {
	chains.RLock()
	defer chains.RUnlock()
	if c, ok := chains.list[cid]; ok {
462
		return c.cs.bundleSource.StableBundle()
463
464
465
466
	}
	return nil
}

467
468
469
470
471
472
473
474
475
476
477
// GetChannelConfig returns the channel configuration of the chain with channel ID. Note that this
// call returns nil if chain cid has not been created.
func GetChannelConfig(cid string) channelconfig.Resources {
	chains.RLock()
	defer chains.RUnlock()
	if c, ok := chains.list[cid]; ok {
		return c.cs
	}
	return nil
}

478
479
480
481
482
483
484
485
486
487
488
// GetPolicyManager returns the policy manager of the chain with chain ID. Note that this
// call returns nil if chain cid has not been created.
func GetPolicyManager(cid string) policies.Manager {
	chains.RLock()
	defer chains.RUnlock()
	if c, ok := chains.list[cid]; ok {
		return c.cs.PolicyManager()
	}
	return nil
}

489
490
491
492
493
494
495
496
497
498
499
// GetCurrConfigBlock returns the cached config block of the specified chain.
// Note that this call returns nil if chain cid has not been created.
func GetCurrConfigBlock(cid string) *common.Block {
	chains.RLock()
	defer chains.RUnlock()
	if c, ok := chains.list[cid]; ok {
		return c.cb
	}
	return nil
}

500
// updates the trusted roots for the peer based on updates to channels
501
func updateTrustedRoots(cm channelconfig.Resources) {
502
	// this is triggered on per channel basis so first update the roots for the channel
503
	peerLogger.Debugf("Updating trusted root authorities for channel %s", cm.ConfigtxValidator().ChainID())
504
	var serverConfig comm.ServerConfig
505
506
	var err error
	// only run is TLS is enabled
507
508
	serverConfig, err = GetServerConfig()
	if err == nil && serverConfig.SecOpts.UseTLS {
509
510
511
512
		buildTrustedRootsForChain(cm)

		// now iterate over all roots for all app and orderer chains
		trustedRoots := [][]byte{}
513
514
515
		credSupport.RLock()
		defer credSupport.RUnlock()
		for _, roots := range credSupport.AppRootCAsByChain {
516
517
518
			trustedRoots = append(trustedRoots, roots...)
		}
		// also need to append statically configured root certs
519
520
		if len(serverConfig.SecOpts.ClientRootCAs) > 0 {
			trustedRoots = append(trustedRoots, serverConfig.SecOpts.ClientRootCAs...)
521
		}
522
523
		if len(serverConfig.SecOpts.ServerRootCAs) > 0 {
			trustedRoots = append(trustedRoots, serverConfig.SecOpts.ServerRootCAs...)
524
525
		}

526
		server := peerServer
527
528
529
530
531
532
533
		// now update the client roots for the peerServer
		if server != nil {
			err := server.SetClientRootCAs(trustedRoots)
			if err != nil {
				msg := "Failed to update trusted roots for peer from latest config " +
					"block.  This peer may not be able to communicate " +
					"with members of channel %s (%s)"
534
				peerLogger.Warningf(msg, cm.ConfigtxValidator().ChainID(), err)
535
536
537
538
539
540
			}
		}
	}
}

// populates the appRootCAs and orderRootCAs maps by getting the
541
// root and intermediate certs for all msps associated with the MSPManager
542
func buildTrustedRootsForChain(cm channelconfig.Resources) {
543
544
	credSupport.Lock()
	defer credSupport.Unlock()
545
546
547

	appRootCAs := [][]byte{}
	ordererRootCAs := [][]byte{}
548
	appOrgMSPs := make(map[string]struct{})
549
550
551
	ordOrgMSPs := make(map[string]struct{})

	if ac, ok := cm.ApplicationConfig(); ok {
552
553
554
555
		//loop through app orgs and build map of MSPIDs
		for _, appOrg := range ac.Organizations() {
			appOrgMSPs[appOrg.MSPID()] = struct{}{}
		}
556
	}
557

558
559
560
561
562
563
564
	if ac, ok := cm.OrdererConfig(); ok {
		//loop through orderer orgs and build map of MSPIDs
		for _, ordOrg := range ac.Organizations() {
			ordOrgMSPs[ordOrg.MSPID()] = struct{}{}
		}
	}

565
	cid := cm.ConfigtxValidator().ChainID()
566
	peerLogger.Debugf("updating root CAs for channel [%s]", cid)
567
568
	msps, err := cm.MSPManager().GetMSPs()
	if err != nil {
569
		peerLogger.Errorf("Error getting root CAs for channel %s (%s)", cid, err)
570
571
	}
	if err == nil {
572
		for k, v := range msps {
573
574
			// check to see if this is a FABRIC MSP
			if v.GetType() == msp.FABRIC {
575
576
577
578
579
				for _, root := range v.GetTLSRootCerts() {
					// check to see of this is an app org MSP
					if _, ok := appOrgMSPs[k]; ok {
						peerLogger.Debugf("adding app root CAs for MSP [%s]", k)
						appRootCAs = append(appRootCAs, root)
580
581
582
					}
					// check to see of this is an orderer org MSP
					if _, ok := ordOrgMSPs[k]; ok {
583
584
						peerLogger.Debugf("adding orderer root CAs for MSP [%s]", k)
						ordererRootCAs = append(ordererRootCAs, root)
585
586
					}
				}
587
588
589
590
591
				for _, intermediate := range v.GetTLSIntermediateCerts() {
					// check to see of this is an app org MSP
					if _, ok := appOrgMSPs[k]; ok {
						peerLogger.Debugf("adding app root CAs for MSP [%s]", k)
						appRootCAs = append(appRootCAs, intermediate)
592
593
594
					}
					// check to see of this is an orderer org MSP
					if _, ok := ordOrgMSPs[k]; ok {
595
596
						peerLogger.Debugf("adding orderer root CAs for MSP [%s]", k)
						ordererRootCAs = append(ordererRootCAs, intermediate)
597
598
599
600
					}
				}
			}
		}
601
602
		credSupport.AppRootCAsByChain[cid] = appRootCAs
		credSupport.OrdererRootCAsByChain[cid] = ordererRootCAs
603
604
605
	}
}

606
607
608
609
// GetMSPIDs returns the ID of each application MSP defined on this chain
func GetMSPIDs(cid string) []string {
	chains.RLock()
	defer chains.RUnlock()
610
611
612
613
614
615

	//if mock is set, use it to return MSPIDs
	//used for tests without a proper join
	if mockMSPIDGetter != nil {
		return mockMSPIDGetter(cid)
	}
616
	if c, ok := chains.list[cid]; ok {
617
618
619
620
621
		if c == nil || c.cs == nil {
			return nil
		}
		ac, ok := c.cs.ApplicationConfig()
		if !ok || ac.Organizations() == nil {
622
623
624
			return nil
		}

625
		orgs := ac.Organizations()
626
627
628
629
630
631
632
633
634
635
636
637
		toret := make([]string, len(orgs))
		i := 0
		for _, org := range orgs {
			toret[i] = org.MSPID()
			i++
		}

		return toret
	}
	return nil
}

638
// SetCurrConfigBlock sets the current config block of the specified channel
639
640
641
642
643
644
645
func SetCurrConfigBlock(block *common.Block, cid string) error {
	chains.Lock()
	defer chains.Unlock()
	if c, ok := chains.list[cid]; ok {
		c.cb = block
		return nil
	}
646
	return errors.Errorf("[channel %s] channel not associated with this peer", cid)
647
648
}

649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
// GetLocalIP returns the non loopback local IP of the host
func GetLocalIP() string {
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		return ""
	}
	for _, address := range addrs {
		// check the address type and if it is not a loopback then display it
		if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
			if ipnet.IP.To4() != nil {
				return ipnet.IP.String()
			}
		}
	}
	return ""
}

666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
// GetChannelsInfo returns an array with information about all channels for
// this peer
func GetChannelsInfo() []*pb.ChannelInfo {
	// array to store metadata for all channels
	var channelInfoArray []*pb.ChannelInfo

	chains.RLock()
	defer chains.RUnlock()
	for key := range chains.list {
		channelInfo := &pb.ChannelInfo{ChannelId: key}

		// add this specific chaincode's metadata to the array of all chaincodes
		channelInfoArray = append(channelInfoArray, channelInfo)
	}

	return channelInfoArray
}

684
685
686
// NewChannelPolicyManagerGetter returns a new instance of ChannelPolicyManagerGetter
func NewChannelPolicyManagerGetter() policies.ChannelPolicyManagerGetter {
	return &channelPolicyManagerGetter{}
687
688
}

689
type channelPolicyManagerGetter struct{}
690

691
692
func (c *channelPolicyManagerGetter) Manager(channelID string) (policies.Manager, bool) {
	policyManager := GetPolicyManager(channelID)
693
694
	return policyManager, policyManager != nil
}
695

696
// NewPeerServer creates an instance of comm.GRPCServer
697
// This server is used for peer communications
698
func NewPeerServer(listenAddress string, serverConfig comm.ServerConfig) (*comm.GRPCServer, error) {
699
	var err error
700
	peerServer, err = comm.NewGRPCServer(listenAddress, serverConfig)
701
702
703
704
705
706
707
	if err != nil {
		peerLogger.Errorf("Failed to create peer server (%s)", err)
		return nil, err
	}
	return peerServer, nil
}

708
709
710
711
712
713
714
715
716
717
// TODO: Remove CollectionSupport and respective methonds on them.
// CollectionSupport is created per chain and is passed to the simple
// collection store and the gossip. As it is created per chain, there
// is no need to pass the channelID for both GetQueryExecutorForLedger()
// and GetIdentityDeserializer(). Note that the cid passed to
// GetQueryExecutorForLedger is never used. Instead, we can directly
// pass the ledger.PeerLedger and msp.IdentityDeserializer to the
// simpleCollectionStore and pass only the msp.IdentityDeserializer to
// the gossip in createChain() -- FAB-13037
type CollectionSupport struct {
718
719
720
	ledger.PeerLedger
}

721
func (cs *CollectionSupport) GetQueryExecutorForLedger(cid string) (ledger.QueryExecutor, error) {
722
723
724
	return cs.NewQueryExecutor()
}

725
func (*CollectionSupport) GetIdentityDeserializer(chainID string) msp.IdentityDeserializer {
726
727
728
	return mspmgmt.GetManagerForChain(chainID)
}

729
730
731
732
//
//  Deliver service support structs for the peer
//

733
734
// DeliverChainManager provides access to a channel for performing deliver
type DeliverChainManager struct {
735
736
}

737
func (DeliverChainManager) GetChain(chainID string) deliver.Chain {
738
	channel, ok := chains.list[chainID]
739
	if !ok {
740
		return nil
741
	}
742
	return channel.cs
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
}

// fileLedgerBlockStore implements the interface expected by
// common/ledger/blockledger/file to interact with a file ledger for deliver
type fileLedgerBlockStore struct {
	ledger.PeerLedger
}

func (flbs fileLedgerBlockStore) AddBlock(*common.Block) error {
	return nil
}

func (flbs fileLedgerBlockStore) RetrieveBlocks(startBlockNumber uint64) (commonledger.ResultsIterator, error) {
	return flbs.GetBlocksIterator(startBlockNumber)
}
758

759
// NewConfigSupport returns
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
func NewConfigSupport() cc.Manager {
	return &configSupport{}
}

type configSupport struct {
}

// GetChannelConfig returns an instance of a object that represents
// current channel configuration tree of the specified channel. The
// ConfigProto method of the returned object can be used to get the
// proto representing the channel configuration.
func (*configSupport) GetChannelConfig(channel string) cc.Config {
	chains.RLock()
	defer chains.RUnlock()
	chain := chains.list[channel]
	if chain == nil {
776
		peerLogger.Errorf("[channel %s] channel not associated with this peer", channel)
777
778
779
780
		return nil
	}
	return chain.cs.bundleSource.ConfigtxValidator()
}