-
Notifications
You must be signed in to change notification settings - Fork 23
Assembler synchronizer integration #962
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
DorKatzelnick
wants to merge
3
commits into
hyperledger:main
Choose a base branch
from
DorKatzelnick:assemblerSynInt
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ import ( | |
| "fmt" | ||
| "sync" | ||
|
|
||
| "github.com/hyperledger/fabric-lib-go/bccsp/factory" | ||
| "github.com/hyperledger/fabric-lib-go/common/flogging" | ||
| "github.com/hyperledger/fabric-protos-go-apiv2/common" | ||
| "github.com/hyperledger/fabric-protos-go-apiv2/orderer" | ||
|
|
@@ -19,6 +20,7 @@ import ( | |
| "github.com/hyperledger/fabric-x-orderer/common/operations" | ||
| common_utils "github.com/hyperledger/fabric-x-orderer/common/utils" | ||
| "github.com/hyperledger/fabric-x-orderer/config" | ||
| "github.com/hyperledger/fabric-x-orderer/node/assembler/synchronizer" | ||
| node_config "github.com/hyperledger/fabric-x-orderer/node/config" | ||
| "github.com/hyperledger/fabric-x-orderer/node/consensus/state" | ||
| "github.com/hyperledger/fabric-x-orderer/node/delivery" | ||
|
|
@@ -60,6 +62,8 @@ func (a *Assembler) Deliver(server orderer.AtomicBroadcast_DeliverServer) error | |
|
|
||
| // GetTxCount returns the number of transactions the assembler stored in the ledger. This method is used only in testing. | ||
| func (a *Assembler) GetTxCount() uint64 { | ||
| a.lock.RLock() | ||
| defer a.lock.RUnlock() | ||
| return a.collator.Ledger.(node_ledger.AssemblerLedgerReaderWriter).GetTxCount() | ||
| } | ||
|
|
||
|
|
@@ -125,6 +129,7 @@ func NewDefaultAssembler( | |
| batchBringerFactory BatchBringerFactory, | ||
| consensusBringerFactory delivery.ConsensusBringerFactory, | ||
| signer identity.SignerSerializer, | ||
| synchronizerFactory synchronizer.SynchronizerFactory, | ||
| ) *Assembler { | ||
| logger.Infof("Creating assembler, party: %d, address: %s", nodeConfig.PartyId, nodeConfig.ListenAddress) | ||
| if configBlock == nil { | ||
|
|
@@ -142,15 +147,19 @@ func NewDefaultAssembler( | |
| } | ||
|
|
||
| assembler := &Assembler{ | ||
| logger: logger, | ||
| ledger: ledger, | ||
| mainExitChan: mainExitChan, | ||
| status: utils.NodeStatus{}, | ||
| metrics: NewMetrics(nodeConfig, ledger.Metrics(), logger), | ||
| signer: signer, | ||
| logger: logger, | ||
| ledger: ledger, | ||
| mainExitChan: mainExitChan, | ||
| status: utils.NodeStatus{}, | ||
| metrics: NewMetrics(nodeConfig, ledger.Metrics(), logger), | ||
| signer: signer, | ||
| assemblerNodeConfig: nodeConfig, | ||
| configuration: configuration, | ||
| } | ||
|
|
||
| assembler.initLedger(configBlock) | ||
| assembler.initLedger(configBlock, nodeConfig, synchronizerFactory) | ||
|
|
||
| // todo - take last config block from ledger and bootstrap the assembler with it | ||
|
|
||
| assembler.initFromConfig(net, nodeConfig, configuration, configBlock, prefetchIndexFactory, prefetcherFactory, batchBringerFactory, consensusBringerFactory) | ||
|
|
||
|
|
@@ -226,43 +235,69 @@ func (a *Assembler) initFromConfig( | |
| a.logger.Infof("Assembler initialized successfully with config sequence number: %d", configSequence) | ||
| } | ||
|
|
||
| func (a *Assembler) initLedger(configBlock *common.Block) { | ||
| var transactionCount, blocksCount uint64 | ||
| height := a.ledger.LedgerReader().Height() | ||
| if height > 0 { | ||
| block, err := a.ledger.LedgerReader().RetrieveBlockByNumber(height - 1) | ||
| func (a *Assembler) initLedger(configBlock *common.Block, nodeConfig *node_config.AssemblerNodeConfig, synchronizerFactory synchronizer.SynchronizerFactory) { | ||
| ledgerHeight := a.ledger.LedgerReader().Height() | ||
| configBlockNumber := configBlock.GetHeader().GetNumber() | ||
| a.logger.Infof("Initializing assembler ledger, current height: %d, config block number: %d", ledgerHeight, configBlockNumber) | ||
|
|
||
| if configBlockNumber == 0 && ledgerHeight == 0 { | ||
| // append config block only if it is the genesis block and the ledger is empty. | ||
| configBlock.Metadata.Metadata[common.BlockMetadataIndex_ORDERER] = common_utils.GenesisBlockMetadataBytes() | ||
| ordInfo := &state.OrderingInformation{ | ||
| CommonBlock: configBlock, | ||
| DecisionNum: 0, | ||
| BatchIndex: 0, | ||
| BatchCount: 1, | ||
| } | ||
| a.ledger.AppendConfig(ordInfo) | ||
| a.logger.Infof("Appended genesis block, header digest: %s", hex.EncodeToString(protoutil.BlockHeaderHash(configBlock.GetHeader()))) | ||
| } else if configBlockNumber > ledgerHeight { | ||
| // genesis block is block number 0, so if config block number is higher than ledger height, it means the assembler needs to sync to the config block before starting. | ||
| a.logger.Warnf("Config block number %d is higher than current ledger height %d, assembler will need to sync to the config block", configBlockNumber, ledgerHeight) | ||
|
Comment on lines
+254
to
+256
|
||
| a.logger.Infof("Creating assembler synchronizer to sync to config block number %d, current ledger height is %d", configBlockNumber, ledgerHeight) | ||
| targetHeight := configBlockNumber + 1 | ||
| synchronizer := synchronizerFactory.CreateSynchronizer( | ||
| a.logger, | ||
| uint64(nodeConfig.PartyId), | ||
| config.Cluster{SendBufferSize: 100, ClientCertificate: nodeConfig.TLSCertificateFile, ClientPrivateKey: nodeConfig.TLSPrivateKeyFile, ReplicationPolicy: "assemblerSync"}, | ||
| &AssemblerSupportAdapter{assembler: a}, | ||
| factory.GetDefault(), | ||
| targetHeight, | ||
| configBlock, | ||
| ) | ||
|
|
||
| err := synchronizer.Sync() | ||
| if err != nil { | ||
| a.logger.Panicf("error while syncing to config block %v", err) | ||
| } | ||
| } else { | ||
| // todo - should panic? | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not panic - this is the normal case when restarting after boot or join |
||
| a.logger.Infof("Assembler is starting with config block already in the ledger, config block number: %d, current ledger height: %d", configBlockNumber, ledgerHeight) | ||
| } | ||
|
|
||
| ledgerHeight = a.ledger.LedgerReader().Height() | ||
| if ledgerHeight == 0 { | ||
| a.logger.Panicf("Assembler ledger is empty after initialization, this should not happen") | ||
| } | ||
|
|
||
| // update metrics with current ledger state only if we didn't just append the genesis block | ||
| // (if we just appended genesis block, metrics were already updated in AppendConfig) | ||
| // This happens when the assembler is restarting with an existing ledger or after syncing | ||
| if ledgerHeight > 1 || configBlockNumber > 0 { | ||
| var transactionCount uint64 | ||
| block, err := a.ledger.LedgerReader().RetrieveBlockByNumber(ledgerHeight - 1) | ||
| if err != nil { | ||
| a.logger.Panicf("error while fetching last block from ledger %v", err) | ||
| } | ||
| _, _, transactionCount, err = node_ledger.AssemblerBatchIdOrderingInfoAndTxCountFromBlock(block) | ||
| if err != nil { | ||
| a.logger.Panicf("error while fetching last block ordering info %v", err) | ||
| } | ||
|
|
||
| blocksCount = height | ||
| } | ||
| a.ledger.Metrics().TransactionCount.Add(float64(transactionCount)) | ||
| a.ledger.Metrics().BlocksCount.Add(float64(blocksCount)) | ||
|
|
||
| a.logger.Infof("Starting with ledger height: %d", a.ledger.LedgerReader().Height()) | ||
|
|
||
| if a.ledger.LedgerReader().Height() == 0 { | ||
| // append config block only if it is the genesis block | ||
| blockNumber := configBlock.GetHeader().Number | ||
| if blockNumber == 0 { | ||
| configBlock.Metadata.Metadata[common.BlockMetadataIndex_ORDERER] = common_utils.GenesisBlockMetadataBytes() | ||
| ordInfo := &state.OrderingInformation{ | ||
| CommonBlock: configBlock, | ||
| DecisionNum: 0, | ||
| BatchIndex: 0, | ||
| BatchCount: 1, | ||
| } | ||
| a.ledger.AppendConfig(ordInfo) | ||
| a.logger.Infof("Appended genesis block, header digest: %s", hex.EncodeToString(protoutil.BlockHeaderHash(configBlock.GetHeader()))) | ||
| } else { | ||
| a.logger.Infof("Assembler started with non-genesis config block, block number: %d", blockNumber) | ||
| } | ||
| a.ledger.Metrics().TransactionCount.Add(float64(transactionCount)) | ||
| a.ledger.Metrics().BlocksCount.Add(float64(ledgerHeight)) | ||
| } | ||
|
|
||
| a.logger.Infof("Ledger was initialized, current ledger height: %d", ledgerHeight) | ||
| } | ||
|
|
||
| func NewAssembler(nodeConfig *node_config.AssemblerNodeConfig, configuration *config.Configuration, configBlock *common.Block, mainExitChan chan struct{}, logger *flogging.FabricLogger, signer identity.SignerSerializer) *Assembler { | ||
|
|
@@ -279,6 +314,7 @@ func NewAssembler(nodeConfig *node_config.AssemblerNodeConfig, configuration *co | |
| &DefaultBatchBringerFactory{}, | ||
| &delivery.DefaultConsensusBringerFactory{}, | ||
| signer, | ||
| &synchronizer.SynchronizerCreator{}, | ||
| ) | ||
| } | ||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unit test |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| /* | ||
| Copyright IBM Corp. All Rights Reserved. | ||
|
|
||
| SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package synchronizer | ||
|
|
||
| import ( | ||
| "github.com/hyperledger/fabric-lib-go/bccsp" | ||
| "github.com/hyperledger/fabric-lib-go/common/flogging" | ||
| "github.com/hyperledger/fabric-protos-go-apiv2/common" | ||
| "github.com/hyperledger/fabric-x-orderer/common/deliverclient" | ||
| ) | ||
|
|
||
| //go:generate counterfeiter -o mocks/verifier_factory.go --fake-name VerifierFactory . VerifierFactory | ||
| type VerifierFactory interface { | ||
| CreateBlockVerifier( | ||
| configBlock *common.Block, | ||
| lastBlock *common.Block, | ||
| cryptoProvider bccsp.BCCSP, | ||
| lg *flogging.FabricLogger, | ||
| ) (deliverclient.CloneableUpdatableBlockVerifier, error) | ||
| } | ||
|
|
||
| // noopVerifierCreator creates a block verifier that does not actually verify blocks, which can be used in tests or when block verification is not needed. | ||
| type noopVerifierCreator struct{} | ||
|
|
||
| func (*noopVerifierCreator) CreateBlockVerifier( | ||
| configBlock *common.Block, | ||
| lastBlock *common.Block, | ||
| cryptoProvider bccsp.BCCSP, | ||
| lg *flogging.FabricLogger, | ||
| ) (deliverclient.CloneableUpdatableBlockVerifier, error) { | ||
| return &noopBlockVerifier{}, nil | ||
| } | ||
|
|
||
| // noopBlockVerifier is a block verifier that does not actually verify blocks, which can be used in tests or when block verification is not needed. | ||
| type noopBlockVerifier struct{} | ||
|
|
||
| // VerifyBlock checks block integrity and its relation to the chain, and verifies the signatures. | ||
| func (*noopBlockVerifier) VerifyBlock(block *common.Block) error { | ||
| // TODO | ||
| return nil | ||
| } | ||
|
|
||
| func (*noopBlockVerifier) VerifyBlockAttestation(block *common.Block) error { | ||
| // TODO | ||
| return nil | ||
| } | ||
|
|
||
| func (*noopBlockVerifier) UpdateConfig(configBlock *common.Block) error { | ||
| // TODO | ||
| return nil | ||
| } | ||
|
|
||
| func (*noopBlockVerifier) UpdateBlockHeader(block *common.Block) { | ||
| // TODO | ||
| } | ||
|
|
||
| func (*noopBlockVerifier) Clone() deliverclient.CloneableUpdatableBlockVerifier { | ||
| return &noopBlockVerifier{} | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Info, not warning