111 lines
3.3 KiB
Go
111 lines
3.3 KiB
Go
/*
|
|
Copyright IBM Corp. All Rights Reserved.
|
|
|
|
SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
package etcdraft
|
|
|
|
import (
|
|
"encoding/pem"
|
|
|
|
"github.com/hyperledger/fabric-protos-go/common"
|
|
"github.com/hyperledger/fabric/bccsp"
|
|
"github.com/hyperledger/fabric/common/flogging"
|
|
"github.com/hyperledger/fabric/orderer/common/cluster"
|
|
"github.com/hyperledger/fabric/orderer/common/localconfig"
|
|
"github.com/hyperledger/fabric/orderer/consensus"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// LedgerBlockPuller pulls blocks upon demand, or fetches them from the ledger
|
|
type LedgerBlockPuller struct {
|
|
BlockPuller
|
|
BlockRetriever cluster.BlockRetriever
|
|
Height func() uint64
|
|
}
|
|
|
|
func (lp *LedgerBlockPuller) PullBlock(seq uint64) *common.Block {
|
|
lastSeq := lp.Height() - 1
|
|
if lastSeq >= seq {
|
|
return lp.BlockRetriever.Block(seq)
|
|
}
|
|
return lp.BlockPuller.PullBlock(seq)
|
|
}
|
|
|
|
// EndpointconfigFromSupport extracts TLS CA certificates and endpoints from the ConsenterSupport
|
|
func EndpointconfigFromSupport(support consensus.ConsenterSupport, bccsp bccsp.BCCSP) ([]cluster.EndpointCriteria, error) {
|
|
lastConfigBlock, err := lastConfigBlockFromSupport(support)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
endpointconf, err := cluster.EndpointconfigFromConfigBlock(lastConfigBlock, bccsp)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return endpointconf, nil
|
|
}
|
|
|
|
func lastConfigBlockFromSupport(support consensus.ConsenterSupport) (*common.Block, error) {
|
|
lastBlockSeq := support.Height() - 1
|
|
lastBlock := support.Block(lastBlockSeq)
|
|
if lastBlock == nil {
|
|
return nil, errors.Errorf("unable to retrieve block [%d]", lastBlockSeq)
|
|
}
|
|
lastConfigBlock, err := cluster.LastConfigBlock(lastBlock, support)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return lastConfigBlock, nil
|
|
}
|
|
|
|
// NewBlockPuller creates a new block puller
|
|
func NewBlockPuller(support consensus.ConsenterSupport,
|
|
baseDialer *cluster.PredicateDialer,
|
|
clusterConfig localconfig.Cluster,
|
|
bccsp bccsp.BCCSP,
|
|
) (BlockPuller, error) {
|
|
verifyBlockSequence := func(blocks []*common.Block, _ string) error {
|
|
vb := cluster.BlockVerifierBuilder(bccsp)
|
|
return cluster.VerifyBlocksBFT(blocks, support.SignatureVerifier(), vb)
|
|
}
|
|
|
|
stdDialer := &cluster.StandardDialer{
|
|
Config: baseDialer.Config,
|
|
}
|
|
stdDialer.Config.AsyncConnect = false
|
|
stdDialer.Config.SecOpts.VerifyCertificate = nil
|
|
|
|
// Extract the TLS CA certs and endpoints from the configuration,
|
|
endpoints, err := EndpointconfigFromSupport(support, bccsp)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
der, _ := pem.Decode(stdDialer.Config.SecOpts.Certificate)
|
|
if der == nil {
|
|
return nil, errors.Errorf("client certificate isn't in PEM format: %v",
|
|
string(stdDialer.Config.SecOpts.Certificate))
|
|
}
|
|
|
|
bp := &cluster.BlockPuller{
|
|
VerifyBlockSequence: verifyBlockSequence,
|
|
Logger: flogging.MustGetLogger("orderer.common.cluster.puller").With("channel", support.ChannelID()),
|
|
RetryTimeout: clusterConfig.ReplicationRetryTimeout,
|
|
MaxTotalBufferBytes: clusterConfig.ReplicationBufferSize,
|
|
FetchTimeout: clusterConfig.ReplicationPullTimeout,
|
|
Endpoints: endpoints,
|
|
Signer: support,
|
|
TLSCert: der.Bytes,
|
|
Channel: support.ChannelID(),
|
|
Dialer: stdDialer,
|
|
StopChannel: make(chan struct{}),
|
|
}
|
|
|
|
return &LedgerBlockPuller{
|
|
Height: support.Height,
|
|
BlockRetriever: support,
|
|
BlockPuller: bp,
|
|
}, nil
|
|
}
|