Skip to content

Commit 5be7273

Browse files
authored
use common block prev hash (#258)
* use common block prev hash Signed-off-by: Hagar Meir <[email protected]> * sign over common block headers Signed-off-by: Hagar Meir <[email protected]> * address review comments Signed-off-by: Hagar Meir <[email protected]> --------- Signed-off-by: Hagar Meir <[email protected]>
1 parent b9017cb commit 5be7273

File tree

8 files changed

+154
-150
lines changed

8 files changed

+154
-150
lines changed

node/assembler/oba_utils_test.go

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ func NewOrderedBatchAttestationCreator() (*OrderedBatchAttestationCreator, *stat
2929
ba := &state.AvailableBatchOrdered{
3030
AvailableBatch: state.NewAvailableBatch(0, math.MaxUint16, 0, genesisDigest),
3131
OrderingInformation: &state.OrderingInformation{
32+
CommonBlock: &common.Block{Header: &common.BlockHeader{Number: 0, PreviousHash: nil, DataHash: genesisDigest}},
3233
BlockHeader: &state.BlockHeader{
3334
Number: 0,
3435
PrevHash: nil,
@@ -41,7 +42,7 @@ func NewOrderedBatchAttestationCreator() (*OrderedBatchAttestationCreator, *stat
4142
}
4243
orderedBatchAttestationCreator := &OrderedBatchAttestationCreator{
4344
prevBa: ba,
44-
headerHash: calculateHeaderHash(ba.OrderingInformation.BlockHeader),
45+
headerHash: protoutil.BlockHeaderHash(ba.OrderingInformation.CommonBlock.Header),
4546
}
4647
return orderedBatchAttestationCreator, ba
4748
}
@@ -58,22 +59,13 @@ func (obac *OrderedBatchAttestationCreator) Append(batchId types.BatchID, decisi
5859
PrevHash: obac.headerHash,
5960
Digest: batchId.Digest(),
6061
},
61-
CommonBlock: &common.Block{Header: &common.BlockHeader{Number: uint64(decisionNum), DataHash: batchId.Digest()}},
62+
CommonBlock: &common.Block{Header: &common.BlockHeader{Number: uint64(decisionNum), PreviousHash: obac.headerHash, DataHash: batchId.Digest()}},
6263
DecisionNum: decisionNum,
6364
BatchIndex: batchIndex,
6465
BatchCount: batchCount,
6566
},
6667
}
67-
obac.headerHash = calculateHeaderHash(ba.OrderingInformation.BlockHeader)
68+
obac.headerHash = protoutil.BlockHeaderHash(ba.OrderingInformation.CommonBlock.Header)
6869
obac.prevBa = ba
6970
return ba
7071
}
71-
72-
func calculateHeaderHash(bh *state.BlockHeader) []byte {
73-
header := &common.BlockHeader{
74-
Number: bh.Number,
75-
PreviousHash: bh.PrevHash,
76-
DataHash: bh.Digest,
77-
}
78-
return protoutil.BlockHeaderHash(header)
79-
}

node/assembler/stub_consenter_test.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ func (sc *stubConsenter) SetNextDecision(ba *state.AvailableBatchOrdered) {
135135
Batch: ba.AvailableBatch,
136136
Header: ba.OrderingInformation.BlockHeader,
137137
}},
138-
AvailableCommonBlocks: []*common.Block{{Header: &common.BlockHeader{Number: ba.OrderingInformation.BlockHeader.Number, DataHash: ba.OrderingInformation.BlockHeader.Digest}}},
138+
AvailableCommonBlocks: []*common.Block{ba.OrderingInformation.CommonBlock},
139139
}).Serialize(),
140140
}
141141

@@ -149,10 +149,7 @@ func (sc *stubConsenter) SetNextDecision(ba *state.AvailableBatchOrdered) {
149149
bytes := state.DecisionToBytes(proposal, signatures)
150150

151151
sc.decisions <- &common.Block{
152-
Header: &common.BlockHeader{
153-
Number: uint64(ba.OrderingInformation.DecisionNum),
154-
PreviousHash: ba.OrderingInformation.PrevHash,
155-
},
156-
Data: &common.BlockData{Data: [][]byte{bytes}},
152+
Header: ba.OrderingInformation.CommonBlock.Header,
153+
Data: &common.BlockData{Data: [][]byte{bytes}},
157154
}
158155
}

node/consensus/consensus.go

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import (
1010
"bytes"
1111
"encoding/asn1"
1212
"encoding/base64"
13+
"encoding/hex"
1314
"fmt"
1415
"io"
15-
"math"
1616
"math/rand"
1717
"sync"
1818

@@ -28,6 +28,7 @@ import (
2828
"github.com/hyperledger/fabric-x-orderer/node/consensus/state"
2929
"github.com/hyperledger/fabric-x-orderer/node/delivery"
3030
protos "github.com/hyperledger/fabric-x-orderer/node/protos/comm"
31+
"github.com/hyperledger/fabric/protoutil"
3132
"github.com/pkg/errors"
3233
"google.golang.org/protobuf/proto"
3334
)
@@ -176,10 +177,12 @@ func (c *Consensus) VerifyProposal(proposal smartbft_types.Proposal) ([]smartbft
176177
c.stateLock.Unlock()
177178

178179
availableBlocks := make([]state.AvailableBlock, len(attestations))
180+
availableCommonBlocks := make([]*common.Block, len(attestations))
181+
179182
for i, ba := range attestations {
180183
availableBlocks[i].Batch = state.NewAvailableBatch(ba[0].Primary(), ba[0].Shard(), ba[0].Seq(), ba[0].Digest())
181184
if !bytes.Equal(hdr.AvailableCommonBlocks[i].Header.DataHash, ba[0].Digest()) {
182-
return nil, fmt.Errorf("proposed available common block data hash in index %d isn't equal to computed digest", i)
185+
return nil, fmt.Errorf("proposed available common block %s data hash in index %d isn't equal to computed digest %s", arma_types.CommonBlockToString(hdr.AvailableCommonBlocks[i]), i, arma_types.BatchIDToString(ba[0]))
183186
}
184187
}
185188

@@ -189,24 +192,28 @@ func (c *Consensus) VerifyProposal(proposal smartbft_types.Proposal) ([]smartbft
189192
}
190193
}
191194

192-
var lastBlockHeader state.BlockHeader
193-
if err := lastBlockHeader.FromBytes(computedState.AppContext); err != nil {
194-
c.Logger.Panicf("Failed deserializing app context to BlockHeader from state: %v", err)
195+
lastCommonBlockHeader := &common.BlockHeader{}
196+
if err := proto.Unmarshal(computedState.AppContext, lastCommonBlockHeader); err != nil {
197+
c.Logger.Panicf("Failed unmarshaling app context to block header from state: %v", err)
195198
}
196199

197-
lastBlockNumber := lastBlockHeader.Number
198-
prevHash := lastBlockHeader.Hash()
199-
if lastBlockNumber == math.MaxUint64 { // This is a signal that we bootstrap
200-
prevHash = nil
201-
}
200+
lastBlockNumber := lastCommonBlockHeader.Number
201+
prevHash := protoutil.BlockHeaderHash(lastCommonBlockHeader)
202202

203203
for i, ba := range attestations {
204204
var bh state.BlockHeader
205205
bh.Digest = ba[0].Digest()
206206
lastBlockNumber++
207+
208+
if hex.EncodeToString(hdr.AvailableCommonBlocks[i].Header.PreviousHash) != hex.EncodeToString(prevHash) {
209+
return nil, fmt.Errorf("proposed common block header prev hash %s in index %d isn't equal to computed prev hash %s, last block number is %d", hex.EncodeToString(hdr.AvailableCommonBlocks[i].Header.PreviousHash), i, hex.EncodeToString(prevHash), lastBlockNumber)
210+
}
211+
212+
availableCommonBlocks[i] = protoutil.NewBlock(lastBlockNumber, prevHash)
213+
availableCommonBlocks[i].Header.DataHash = ba[0].Digest()
207214
bh.Number = lastBlockNumber
208215
bh.PrevHash = prevHash
209-
prevHash = bh.Hash()
216+
prevHash = protoutil.BlockHeaderHash(availableCommonBlocks[i].Header)
210217
availableBlocks[i].Header = &bh
211218

212219
if hdr.AvailableCommonBlocks[i].Header.Number != lastBlockNumber {
@@ -223,7 +230,7 @@ func (c *Consensus) VerifyProposal(proposal smartbft_types.Proposal) ([]smartbft
223230
}
224231

225232
if len(attestations) > 0 {
226-
computedState.AppContext = availableBlocks[len(attestations)-1].Header.Bytes()
233+
computedState.AppContext = protoutil.MarshalOrPanic(availableCommonBlocks[len(attestations)-1].Header)
227234
}
228235

229236
if !bytes.Equal(hdr.State.Serialize(), computedState.Serialize()) {
@@ -285,10 +292,10 @@ func (c *Consensus) VerifyConsenterSig(signature smartbft_types.Signature, prop
285292
return nil, errors.Wrap(err, "failed deserializing proposal header")
286293
}
287294

288-
for i, bh := range hdr.AvailableBlocks {
295+
for i, bh := range hdr.AvailableCommonBlocks {
289296
if err := c.VerifySignature(smartbft_types.Signature{
290297
Value: values[i+1],
291-
Msg: bh.Header.Bytes(),
298+
Msg: protoutil.BlockHeaderBytes(bh.Header),
292299
ID: signature.ID,
293300
}); err != nil {
294301
return nil, errors.Wrap(err, "failed verifying signature over block header")
@@ -393,9 +400,9 @@ func (c *Consensus) SignProposal(proposal smartbft_types.Proposal, _ []byte) *sm
393400

394401
sigs = append(sigs, proposalSig)
395402

396-
for _, bh := range hdr.AvailableBlocks {
397-
msg := bh.Header.Bytes()
398-
sig, err := c.Signer.Sign(msg)
403+
for _, bh := range hdr.AvailableCommonBlocks {
404+
msg := protoutil.BlockHeaderBytes(bh.Header)
405+
sig, err := c.Signer.Sign(msg) // TODO sign like we do in Fabric
399406
if err != nil {
400407
c.Logger.Panicf("Failed signing block header: %v", err)
401408
}
@@ -422,13 +429,13 @@ func (c *Consensus) AssembleProposal(metadata []byte, requests [][]byte) smartbf
422429
newState, attestations := c.Arma.SimulateStateTransition(c.State, requests)
423430
c.stateLock.Unlock()
424431

425-
var lastBlockHeader state.BlockHeader
426-
if err := lastBlockHeader.FromBytes(newState.AppContext); err != nil {
427-
c.Logger.Panicf("Failed deserializing app context to BlockHeader from state: %v", err)
432+
lastCommonBlockHeader := &common.BlockHeader{}
433+
if err := proto.Unmarshal(newState.AppContext, lastCommonBlockHeader); err != nil {
434+
c.Logger.Panicf("Failed unmarshaling app context to block header from state: %v", err)
428435
}
429436

430-
lastBlockNumber := lastBlockHeader.Number
431-
prevHash := lastBlockHeader.Hash()
437+
lastBlockNumber := lastCommonBlockHeader.Number
438+
prevHash := protoutil.BlockHeaderHash(lastCommonBlockHeader)
432439

433440
c.Logger.Infof("Creating proposal with %d attestations", len(attestations))
434441

@@ -437,22 +444,22 @@ func (c *Consensus) AssembleProposal(metadata []byte, requests [][]byte) smartbf
437444

438445
for i, ba := range attestations {
439446
availableBlocks[i].Batch = state.NewAvailableBatch(ba[0].Primary(), ba[0].Shard(), ba[0].Seq(), ba[0].Digest())
440-
availableCommonBlocks[i] = &common.Block{Header: &common.BlockHeader{DataHash: ba[0].Digest()}}
441447
}
442448

443449
for i, ba := range attestations {
444450
var hdr state.BlockHeader
445451
hdr.Digest = ba[0].Digest()
446452
lastBlockNumber++
453+
availableCommonBlocks[i] = protoutil.NewBlock(lastBlockNumber, prevHash)
454+
availableCommonBlocks[i].Header.DataHash = ba[0].Digest()
447455
hdr.Number = lastBlockNumber
448456
hdr.PrevHash = prevHash
449-
prevHash = hdr.Hash()
457+
prevHash = protoutil.BlockHeaderHash(availableCommonBlocks[i].Header)
450458
availableBlocks[i].Header = &hdr
451-
availableCommonBlocks[i].Header.Number = lastBlockNumber
452459
}
453460

454461
if len(attestations) > 0 {
455-
newState.AppContext = availableBlocks[len(attestations)-1].Header.Bytes()
462+
newState.AppContext = protoutil.MarshalOrPanic(availableCommonBlocks[len(attestations)-1].Header)
456463
}
457464

458465
md := &smartbftprotos.ViewMetadata{}

node/consensus/consensus_builder.go

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -250,13 +250,12 @@ func initialStateFromConfig(config *config.ConsenterNodeConfig) *state.State {
250250
return int(initState.Shards[i].Shard) < int(initState.Shards[j].Shard)
251251
})
252252

253-
// TODO set right initial app context
254-
initialAppContext := &state.BlockHeader{
255-
Number: 0, // We want the first block to start with 0, this is how we signal bootstrap
256-
PrevHash: nil,
257-
Digest: nil,
253+
initialAppContext := &common.BlockHeader{
254+
Number: 0, // We want the first block to start with 0, this is how we signal bootstrap
255+
PreviousHash: nil,
256+
DataHash: nil,
258257
}
259-
initState.AppContext = initialAppContext.Bytes()
258+
initState.AppContext = protoutil.MarshalOrPanic(initialAppContext)
260259

261260
return &initState
262261
}
@@ -274,21 +273,24 @@ func appendGenesisBlock(genesisBlock *common.Block, initState *state.State, ledg
274273
Batch: state.NewAvailableBatch(0, arma_types.ShardIDConsensus, 0, genesisDigest),
275274
}
276275

277-
var lastBlockHeader state.BlockHeader
278-
if err := lastBlockHeader.FromBytes(initState.AppContext); err != nil {
279-
panic(fmt.Sprintf("Failed deserializing app context to BlockHeader from initial state: %v", err))
276+
lastCommonBlockHeader := &common.BlockHeader{}
277+
if err := proto.Unmarshal(initState.AppContext, lastCommonBlockHeader); err != nil {
278+
panic(fmt.Sprintf("Failed unmarshaling app context to BlockHeader from initial state: %v", err))
280279
}
281-
lastBlockHeader.Digest = genesisDigest
282-
initState.AppContext = lastBlockHeader.Bytes()
280+
281+
lastCommonBlockHeader.DataHash = genesisDigest
282+
283+
initState.AppContext = protoutil.MarshalOrPanic(lastCommonBlockHeader)
283284

284285
genesisProposal := smartbft_types.Proposal{
285-
Payload: protoutil.MarshalOrPanic(genesisBlock), // TODO create a correct payload
286+
Payload: protoutil.MarshalOrPanic(genesisBlock),
286287
Header: (&state.Header{
287-
AvailableBlocks: genesisBlocks,
288-
State: initState,
289-
Num: 0,
288+
AvailableCommonBlocks: []*common.Block{genesisBlock},
289+
AvailableBlocks: genesisBlocks,
290+
State: initState,
291+
Num: 0,
290292
}).Serialize(),
291-
Metadata: nil, // TODO maybe use this metadata
293+
Metadata: nil,
292294
}
293295

294296
ledger.Append(state.DecisionToBytes(genesisProposal, nil))

0 commit comments

Comments
 (0)