Skip to content

Commit 522c040

Browse files
author
Jason Yellick
committed
[FAB-1698] Add block data hashing structure config
https://jira.hyperledger.org/browse/FAB-1698 This commit adds a proto message for BlockDataHashingStructure which dictates the width of the Merkle tree to use when computing the BlockData hash. It also adds this value to the chainconfig Reader, although no one currently consumes this. Change-Id: I17c4b13a30df8da0c39310be9c0f2a32a76ce859 Signed-off-by: Jason Yellick <[email protected]>
1 parent e057af8 commit 522c040

File tree

5 files changed

+139
-47
lines changed

5 files changed

+139
-47
lines changed

common/chainconfig/chainconfig.go

+25-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ import (
3030
const (
3131
// HashingAlgorithmKey is the cb.ConfigurationItem type key name for the HashingAlgorithm message
3232
HashingAlgorithmKey = "HashingAlgorithm"
33+
34+
// BlockDataHashingStructureKey is the cb.ConfigurationItem type key name for the BlockDataHashingStructure message
35+
BlockDataHashingStructureKey = "BlockDataHashingStructure"
3336
)
3437

3538
// Hashing algorithm types
@@ -48,10 +51,15 @@ type Descriptor interface {
4851
// HashingAlgorithm returns the default algorithm to be used when hashing
4952
// such as computing block hashes, and CreationPolicy digests
5053
HashingAlgorithm() func(input []byte) []byte
54+
55+
// BlockDataHashingStructureWidth returns the width to use when constructing the
56+
// Merkle tree to compute the BlockData hash
57+
BlockDatahashingStructureWidth() int
5158
}
5259

5360
type chainConfig struct {
54-
hashingAlgorithm func(input []byte) []byte
61+
hashingAlgorithm func(input []byte) []byte
62+
blockDataHashingStructureWidth uint32
5563
}
5664

5765
// DescriptorImpl is an implementation of Manager and configtx.ConfigHandler
@@ -73,6 +81,11 @@ func (pm *DescriptorImpl) HashingAlgorithm() func(input []byte) []byte {
7381
return pm.config.hashingAlgorithm
7482
}
7583

84+
// BlockDataHashingStructure returns the width to use when forming the block data hashing structure
85+
func (pm *DescriptorImpl) BlockDataHashingStructureWidth() uint32 {
86+
return pm.config.blockDataHashingStructureWidth
87+
}
88+
7689
// BeginConfig is used to start a new configuration proposal
7790
func (pm *DescriptorImpl) BeginConfig() {
7891
if pm.pendingConfig != nil {
@@ -113,6 +126,17 @@ func (pm *DescriptorImpl) ProposeConfig(configItem *cb.ConfigurationItem) error
113126
default:
114127
return fmt.Errorf("Unknown hashing algorithm type: %s", hashingAlgorithm.Name)
115128
}
129+
case BlockDataHashingStructureKey:
130+
blockDataHashingStructure := &cb.BlockDataHashingStructure{}
131+
if err := proto.Unmarshal(configItem.Value, blockDataHashingStructure); err != nil {
132+
return fmt.Errorf("Unmarshaling error for BlockDataHashingStructure: %s", err)
133+
}
134+
135+
if blockDataHashingStructure.Width == 0 {
136+
return fmt.Errorf("BlockDataHashStructure width must not be zero")
137+
}
138+
139+
pm.pendingConfig.blockDataHashingStructureWidth = blockDataHashingStructure.Width
116140
default:
117141
logger.Warningf("Uknown Chain configuration item with key %s", configItem.Key)
118142
}

common/chainconfig/chainconfig_test.go

+43
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,46 @@ func TestHashingAlgorithm(t *testing.T) {
102102
t.Fatalf("Should have set default hashing algorithm")
103103
}
104104
}
105+
106+
func TestBlockDataHashingStructure(t *testing.T) {
107+
expectedWidth := uint32(7)
108+
invalidMessage :=
109+
&cb.ConfigurationItem{
110+
Type: cb.ConfigurationItem_Chain,
111+
Key: BlockDataHashingStructureKey,
112+
Value: []byte("Garbage Data"),
113+
}
114+
invalidWidth := &cb.ConfigurationItem{
115+
Type: cb.ConfigurationItem_Chain,
116+
Key: BlockDataHashingStructureKey,
117+
Value: utils.MarshalOrPanic(&cb.BlockDataHashingStructure{Width: 0}),
118+
}
119+
validWidth := &cb.ConfigurationItem{
120+
Type: cb.ConfigurationItem_Chain,
121+
Key: BlockDataHashingStructureKey,
122+
Value: utils.MarshalOrPanic(&cb.BlockDataHashingStructure{Width: expectedWidth}),
123+
}
124+
m := NewDescriptorImpl()
125+
m.BeginConfig()
126+
127+
err := m.ProposeConfig(invalidMessage)
128+
if err == nil {
129+
t.Fatalf("Should have failed on invalid message")
130+
}
131+
132+
err = m.ProposeConfig(invalidWidth)
133+
if err == nil {
134+
t.Fatalf("Should have failed on invalid width")
135+
}
136+
137+
err = m.ProposeConfig(validWidth)
138+
if err != nil {
139+
t.Fatalf("Error applying valid config: %s", err)
140+
}
141+
142+
m.CommitConfig()
143+
144+
if newWidth := m.BlockDataHashingStructureWidth(); newWidth != expectedWidth {
145+
t.Fatalf("Unexpected width, got %d expected %d", newWidth, expectedWidth)
146+
}
147+
}

protos/common/common.pb.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

protos/common/configuration.pb.go

+60-44
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

protos/common/configuration.proto

+10-2
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,17 @@ message SignaturePolicy {
118118
}
119119

120120

121-
// HashingAlgorithm is encoded into the configuration transaction as a configuration item of type CHAIN
122-
// with a Key of "HashingAlgorithm" as marshaled protobuf bytes
121+
// HashingAlgorithm is encoded into the configuration transaction as a configuration item of type Chain
122+
// with a Key of "HashingAlgorithm" and a Value of HashingAlgorithm as marshaled protobuf bytes
123123
message HashingAlgorithm {
124124
// Currently supported algorithms are: SHAKE256
125125
string name = 1;
126126
}
127+
128+
// BlockDataHashingStructure is encoded into the configuration transaction as a configuration item of
129+
// type Chain with a Key of "BlockDataHashingStructure" and a Value of HashingAlgorithm as marshaled protobuf bytes
130+
message BlockDataHashingStructure {
131+
// width specifies the width of the Merkle tree to use when computing the BlockDataHash
132+
// in order to replicate flat hashing, set this width to MAX_UINT32
133+
uint32 width = 1;
134+
}

0 commit comments

Comments
 (0)