diff --git a/node/assembler/oba_utils_test.go b/node/assembler/oba_utils_test.go index bd7d8275..cc772f75 100644 --- a/node/assembler/oba_utils_test.go +++ b/node/assembler/oba_utils_test.go @@ -12,6 +12,7 @@ import ( "github.com/hyperledger/fabric-x-orderer/common/types" "github.com/hyperledger/fabric-x-orderer/common/utils" "github.com/hyperledger/fabric-x-orderer/node/consensus/state" + "github.com/hyperledger/fabric-x-orderer/node/ledger" "github.com/hyperledger/fabric-protos-go-apiv2/common" "github.com/hyperledger/fabric/protoutil" @@ -65,6 +66,12 @@ func (obac *OrderedBatchAttestationCreator) Append(batchId types.BatchID, decisi BatchCount: batchCount, }, } + blockMetadata, err := ledger.AssemblerBlockMetadataToBytes(batchId, &state.OrderingInformation{DecisionNum: decisionNum, BatchCount: batchCount, BatchIndex: batchIndex}, 0) + if err != nil { + panic("Failed to invoke AssemblerBlockMetadataToBytes") + } + protoutil.InitBlockMetadata(ba.OrderingInformation.CommonBlock) + ba.OrderingInformation.CommonBlock.Metadata.Metadata[common.BlockMetadataIndex_ORDERER] = blockMetadata obac.headerHash = protoutil.BlockHeaderHash(ba.OrderingInformation.CommonBlock.Header) obac.prevBa = ba return ba diff --git a/node/consensus/consensus.go b/node/consensus/consensus.go index ed36a420..c79a31ab 100644 --- a/node/consensus/consensus.go +++ b/node/consensus/consensus.go @@ -28,6 +28,7 @@ import ( "github.com/hyperledger/fabric-x-orderer/node/consensus/badb" "github.com/hyperledger/fabric-x-orderer/node/consensus/state" "github.com/hyperledger/fabric-x-orderer/node/delivery" + "github.com/hyperledger/fabric-x-orderer/node/ledger" protos "github.com/hyperledger/fabric-x-orderer/node/protos/comm" "github.com/hyperledger/fabric/protoutil" "github.com/pkg/errors" @@ -244,6 +245,19 @@ func (c *Consensus) VerifyProposal(proposal smartbft_types.Proposal) ([]smartbft return nil, fmt.Errorf("proposed common block header number %d in index %d isn't equal to computed number %d", hdr.AvailableCommonBlocks[i].Header.Number, i, lastBlockNumber) } + blockMetadata, err := ledger.AssemblerBlockMetadataToBytes(ba[0], &state.OrderingInformation{DecisionNum: arma_types.DecisionNum(md.LatestSequence), BatchCount: len(attestations), BatchIndex: i}, 0) + if err != nil { + c.Logger.Panicf("Failed to invoke AssemblerBlockMetadataToBytes: %s", err) + } + + if hdr.AvailableCommonBlocks[i].Metadata == nil || hdr.AvailableCommonBlocks[i].Metadata.Metadata == nil { + return nil, fmt.Errorf("proposed common block metadata in index %d is nil", i) + } + + if !bytes.Equal(blockMetadata, hdr.AvailableCommonBlocks[i].Metadata.Metadata[common.BlockMetadataIndex_ORDERER]) { + return nil, fmt.Errorf("proposed common block metadata in index %d isn't equal to computed metadata", i) + } + } for i, availableBlock := range hdr.AvailableBlocks { @@ -325,7 +339,7 @@ func (c *Consensus) VerifySignature(signature smartbft_types.Signature) error { // VerificationSequence returns the current verification sequence // (from SmartBFT API) func (c *Consensus) VerificationSequence() uint64 { - return 0 + return 0 // TODO save current verification sequence and return it here } // RequestsFromProposal returns from the given proposal the included requests' info @@ -448,6 +462,11 @@ func (c *Consensus) AssembleProposal(metadata []byte, requests [][]byte) smartbf lastBlockNumber := lastCommonBlockHeader.Number prevHash := protoutil.BlockHeaderHash(lastCommonBlockHeader) + md := &smartbftprotos.ViewMetadata{} + if err := proto.Unmarshal(metadata, md); err != nil { + panic(err) + } + c.Logger.Infof("Creating proposal with %d attestations", len(attestations)) availableBlocks := make([]state.AvailableBlock, len(attestations)) @@ -463,6 +482,12 @@ func (c *Consensus) AssembleProposal(metadata []byte, requests [][]byte) smartbf lastBlockNumber++ availableCommonBlocks[i] = protoutil.NewBlock(lastBlockNumber, prevHash) availableCommonBlocks[i].Header.DataHash = ba[0].Digest() + blockMetadata, err := ledger.AssemblerBlockMetadataToBytes(ba[0], &state.OrderingInformation{DecisionNum: arma_types.DecisionNum(md.LatestSequence), BatchCount: len(attestations), BatchIndex: i}, 0) + if err != nil { + c.Logger.Panicf("Failed to invoke AssemblerBlockMetadataToBytes: %s", err) + } + protoutil.InitBlockMetadata(availableCommonBlocks[i]) + availableCommonBlocks[i].Metadata.Metadata[common.BlockMetadataIndex_ORDERER] = blockMetadata hdr.Number = lastBlockNumber hdr.PrevHash = prevHash prevHash = protoutil.BlockHeaderHash(availableCommonBlocks[i].Header) @@ -473,11 +498,6 @@ func (c *Consensus) AssembleProposal(metadata []byte, requests [][]byte) smartbf newState.AppContext = protoutil.MarshalOrPanic(availableCommonBlocks[len(attestations)-1].Header) } - md := &smartbftprotos.ViewMetadata{} - if err := proto.Unmarshal(metadata, md); err != nil { - panic(err) - } - reqs := arma_types.BatchedRequests(requests) return smartbft_types.Proposal{ diff --git a/node/consensus/consensus_builder.go b/node/consensus/consensus_builder.go index d02a9334..15673fd9 100644 --- a/node/consensus/consensus_builder.go +++ b/node/consensus/consensus_builder.go @@ -261,7 +261,7 @@ func initialStateFromConfig(config *config.ConsenterNodeConfig) *state.State { return &initState } -func appendGenesisBlock(genesisBlock *common.Block, initState *state.State, ledger *ledger.ConsensusLedger) { +func appendGenesisBlock(genesisBlock *common.Block, initState *state.State, consensusLedger *ledger.ConsensusLedger) { genesisBlocks := make([]state.AvailableBlock, 1) genesisDigest := protoutil.ComputeBlockDataHash(genesisBlock.GetData()) @@ -283,10 +283,21 @@ func appendGenesisBlock(genesisBlock *common.Block, initState *state.State, ledg initState.AppContext = protoutil.MarshalOrPanic(lastCommonBlockHeader) + availableCommonBlocks := []*common.Block{genesisBlock} + + protoutil.InitBlockMetadata(availableCommonBlocks[0]) + + blockMetadata, err := ledger.AssemblerBlockMetadataToBytes(state.NewAvailableBatch(0, arma_types.ShardIDConsensus, 0, genesisDigest), &state.OrderingInformation{DecisionNum: 0, BatchCount: 1, BatchIndex: 0}, 0) + if err != nil { + panic("failed to invoke AssemblerBlockMetadataToBytes") + } + + availableCommonBlocks[0].Metadata.Metadata[common.BlockMetadataIndex_ORDERER] = blockMetadata + genesisProposal := smartbft_types.Proposal{ Payload: protoutil.MarshalOrPanic(genesisBlock), Header: (&state.Header{ - AvailableCommonBlocks: []*common.Block{genesisBlock}, + AvailableCommonBlocks: availableCommonBlocks, AvailableBlocks: genesisBlocks, State: initState, Num: 0, @@ -294,7 +305,7 @@ func appendGenesisBlock(genesisBlock *common.Block, initState *state.State, ledg Metadata: nil, } - ledger.Append(state.DecisionToBytes(genesisProposal, nil)) + consensusLedger.Append(state.DecisionToBytes(genesisProposal, nil)) } func (c *Consensus) clientConfig() comm.ClientConfig { diff --git a/node/consensus/consensus_test.go b/node/consensus/consensus_test.go index 63f6337a..8aff9a1d 100644 --- a/node/consensus/consensus_test.go +++ b/node/consensus/consensus_test.go @@ -717,9 +717,16 @@ func TestVerifyProposal(t *testing.T) { latestBlockHeader.DataHash = baf123id1p1s1.Digest() latestBlockHeader.PreviousHash = protoutil.BlockHeaderHash(initialAppContext) - header.AvailableBlocks = []state.AvailableBlock{{Header: &state.BlockHeader{Number: latestBlockHeader.Number, PrevHash: latestBlockHeader.PreviousHash, Digest: latestBlockHeader.DataHash}, Batch: state.NewAvailableBatch(baf123id1p1s1.Primary(), baf123id1p1s1.Shard(), baf123id1p1s1.Seq(), baf123id1p1s1.Digest())}} + ab := state.NewAvailableBatch(baf123id1p1s1.Primary(), baf123id1p1s1.Shard(), baf123id1p1s1.Seq(), baf123id1p1s1.Digest()) + + header.AvailableBlocks = []state.AvailableBlock{{Header: &state.BlockHeader{Number: latestBlockHeader.Number, PrevHash: latestBlockHeader.PreviousHash, Digest: latestBlockHeader.DataHash}, Batch: ab}} header.AvailableCommonBlocks = []*common.Block{{Header: latestBlockHeader}} + protoutil.InitBlockMetadata(header.AvailableCommonBlocks[0]) + blockMetadata, err := ledger.AssemblerBlockMetadataToBytes(ab, &state.OrderingInformation{DecisionNum: 0, BatchCount: 1, BatchIndex: 0}, 0) + require.Nil(t, err) + header.AvailableCommonBlocks[0].Metadata.Metadata[common.BlockMetadataIndex_ORDERER] = blockMetadata + newState := initialState newState.AppContext = protoutil.MarshalOrPanic(latestBlockHeader) diff --git a/node/delivery/consensus_ba_deliver_client.go b/node/delivery/consensus_ba_deliver_client.go index f29b9e80..c9203e7c 100644 --- a/node/delivery/consensus_ba_deliver_client.go +++ b/node/delivery/consensus_ba_deliver_client.go @@ -111,19 +111,26 @@ func (cr *ConsensusBAReplicator) Replicate() <-chan types.OrderedBatchAttestatio cr.logger.Panicf("Failed extracting ordered batch attestation from decision: %s", err2) } - cr.logger.Infof("Decision %d, with %d AvailableBlocks", block.GetHeader().GetNumber(), len(header.AvailableBlocks)) - for index, ab := range header.AvailableBlocks { - cr.logger.Infof("BA index: %d; BatchID: %s; BA block header: %s; BA block signers: %+v", index, types.BatchIDToString(ab.Batch), ab.Header.String(), signersFromSigs(sigs[index])) + cr.logger.Infof("Decision %d, with %d AvailableCommonBlocks", block.GetHeader().GetNumber(), len(header.AvailableCommonBlocks)) + for index, acb := range header.AvailableCommonBlocks { + + primary, shard, seq, _, _, _, _, err := ledger.AssemblerBlockMetadataFromBytes(acb.Metadata.Metadata[common.BlockMetadataIndex_ORDERER]) + if err != nil { + cr.logger.Panicf("Failed extracting info from metadata: %s", err) + } + + acbBatch := state.NewAvailableBatch(primary, shard, seq, acb.Header.DataHash) + + cr.logger.Infof("BA index: %d; BatchID: %s; Common Block: %s; BA block signers: %+v", index, types.BatchIDToString(acbBatch), types.CommonBlockToString(acb), signersFromSigs(sigs[index])) abo := &state.AvailableBatchOrdered{ - AvailableBatch: ab.Batch, + AvailableBatch: acbBatch, OrderingInformation: &state.OrderingInformation{ CommonBlock: header.AvailableCommonBlocks[index], - BlockHeader: ab.Header, Signatures: sigs[index], DecisionNum: header.Num, BatchIndex: index, - BatchCount: len(header.AvailableBlocks), + BatchCount: len(header.AvailableCommonBlocks), }, } diff --git a/node/delivery/utils.go b/node/delivery/utils.go index 96a9da4f..4552890b 100644 --- a/node/delivery/utils.go +++ b/node/delivery/utils.go @@ -55,7 +55,7 @@ func extractHeaderAndSigsFromBlock(block *common.Block) (*state.Header, [][]smar return stateHeader, sigs, nil } - sigs, err := state.UnpackBlockHeaderSigs(compoundSigs, len(stateHeader.AvailableBlocks)) + sigs, err := state.UnpackBlockHeaderSigs(compoundSigs, len(stateHeader.AvailableCommonBlocks)) if err != nil { return nil, nil, errors.Wrapf(err, "failed to extract header signatures from compound signature, block %d", block.GetHeader().GetNumber()) } diff --git a/node/ledger/assembler_ledger.go b/node/ledger/assembler_ledger.go index 35861a85..26c23d4f 100644 --- a/node/ledger/assembler_ledger.go +++ b/node/ledger/assembler_ledger.go @@ -137,7 +137,7 @@ func (l *AssemblerLedger) Append(batch types.Batch, orderingInfo types.OrderingI t1 := time.Now() defer func() { l.Logger.Infof("Appended block %d of %d requests to ledger in %v", - ordInfo.BlockHeader.Number, len(batch.Requests()), time.Since(t1)) + ordInfo.CommonBlock.Header.Number, len(batch.Requests()), time.Since(t1)) }() block := &common.Block{ @@ -147,11 +147,7 @@ func (l *AssemblerLedger) Append(batch types.Batch, orderingInfo types.OrderingI }, } - var metadataContents [][]byte - for i := 0; i < len(common.BlockMetadataIndex_name); i++ { - metadataContents = append(metadataContents, []byte{}) - } - block.Metadata = &common.BlockMetadata{Metadata: metadataContents} + protoutil.InitBlockMetadata(block) var sigs []*common.MetadataSignature var signers []uint64