Skip to content

Commit fff6ed6

Browse files
committed
[FAB-1690] Implement Chain interface in SBFT
https://jira.hyperledger.org/browse/FAB-1690 Change-Id: I0b0fd0b3df5dc919b77908aae80311fd604b0d4e Signed-off-by: Gabor Hosszu <[email protected]>
1 parent 230f3cc commit fff6ed6

31 files changed

+985
-820
lines changed

orderer/localconfig/config.go

+29
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,20 @@ type Kafka struct {
101101
Version sarama.KafkaVersion
102102
}
103103

104+
// Sbft contains config for the SBFT orderer
105+
type Sbft struct {
106+
PeerCommAddr string
107+
CertFile string
108+
KeyFile string
109+
DataDir string
110+
N uint64
111+
F uint64
112+
BatchDurationNsec uint64
113+
BatchSizeBytes uint64
114+
RequestTimeoutNsec uint64
115+
Peers map[string]string // Address to Cert mapping
116+
}
117+
104118
// Retry contains config for the reconnection attempts to the Kafka brokers
105119
type Retry struct {
106120
Period time.Duration
@@ -118,6 +132,7 @@ type TopLevel struct {
118132
FileLedger FileLedger
119133
Kafka Kafka
120134
Genesis Genesis
135+
Sbft Sbft
121136
}
122137

123138
var defaults = TopLevel{
@@ -161,6 +176,20 @@ var defaults = TopLevel{
161176
PreferredMaxBytes: 512 * 1024,
162177
},
163178
},
179+
// TODO move the appropriate parts to Genesis
180+
// and use BatchSizeMaxBytes
181+
Sbft: Sbft{
182+
PeerCommAddr: ":6101",
183+
CertFile: "sbft/testdata/cert1.pem",
184+
KeyFile: "sbft/testdata/key.pem",
185+
DataDir: "/tmp",
186+
N: 1,
187+
F: 0,
188+
BatchDurationNsec: 1000,
189+
BatchSizeBytes: 1000000000,
190+
RequestTimeoutNsec: 1000000000,
191+
Peers: map[string]string{":6101": "sbft/testdata/cert1.pem"},
192+
},
164193
}
165194

166195
func (c *TopLevel) completeInitialization() {

orderer/localconfig/config_util.go

+20
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import (
2525
"strings"
2626
"time"
2727

28+
"encoding/json"
29+
2830
"github.com/mitchellh/mapstructure"
2931
"github.com/spf13/viper"
3032
)
@@ -48,6 +50,9 @@ func getKeysRecursively(base string, v *viper.Viper, nodeKeys map[string]interfa
4850
} else if m, ok := val.(map[string]interface{}); ok {
4951
logger.Debugf("Found map[string]interface{} value for %s", fqKey)
5052
result[key] = getKeysRecursively(fqKey+".", v, m)
53+
} else if m, ok := unmarshalJson(val); ok {
54+
logger.Debugf("Found real value for %s setting to map[string]string %v", fqKey, m)
55+
result[key] = m
5156
} else {
5257
logger.Debugf("Found real value for %s setting to %T %v", fqKey, val, val)
5358
result[key] = val
@@ -56,6 +61,21 @@ func getKeysRecursively(base string, v *viper.Viper, nodeKeys map[string]interfa
5661
return result
5762
}
5863

64+
func unmarshalJson(val interface{}) (map[string]string, bool) {
65+
mp := map[string]string{}
66+
s, ok := val.(string)
67+
if !ok {
68+
logger.Debugf("Unmarshal JSON: value is not a string: %v", val)
69+
return nil, false
70+
}
71+
err := json.Unmarshal([]byte(s), &mp)
72+
if err != nil {
73+
logger.Debugf("Unmarshal JSON: value cannot be unmarshalled: %s", err)
74+
return nil, false
75+
}
76+
return mp, true
77+
}
78+
5979
// customDecodeHook adds the additional functions of parsing durations from strings
6080
// as well as parsing strings of the format "[thing1, thing2, thing3]" into string slices
6181
// Note that whitespace around slice elements is removed

orderer/main.go

+23
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ import (
3535
ramledger "github.com/hyperledger/fabric/orderer/ledger/ram"
3636
"github.com/hyperledger/fabric/orderer/localconfig"
3737
"github.com/hyperledger/fabric/orderer/multichain"
38+
"github.com/hyperledger/fabric/orderer/sbft"
39+
"github.com/hyperledger/fabric/orderer/sbft/backend"
40+
sbftcrypto "github.com/hyperledger/fabric/orderer/sbft/crypto"
41+
"github.com/hyperledger/fabric/orderer/sbft/simplebft"
3842
"github.com/hyperledger/fabric/orderer/solo"
3943
cb "github.com/hyperledger/fabric/protos/common"
4044
ab "github.com/hyperledger/fabric/protos/orderer"
@@ -144,6 +148,7 @@ func main() {
144148
consenters := make(map[string]multichain.Consenter)
145149
consenters["solo"] = solo.New()
146150
consenters["kafka"] = kafka.New(conf.Kafka.Version, conf.Kafka.Retry)
151+
consenters["sbft"] = sbft.New(makeSbftConsensusConfig(conf), makeSbftStackConfig(conf))
147152

148153
manager := multichain.NewManagerImpl(lf, consenters, localmsp.NewSigner())
149154

@@ -157,3 +162,21 @@ func main() {
157162
logger.Infof("Beginning to serve requests")
158163
grpcServer.Start()
159164
}
165+
166+
func makeSbftConsensusConfig(conf *config.TopLevel) *sbft.ConsensusConfig {
167+
cfg := simplebft.Config{N: conf.Sbft.N, F: conf.Sbft.F, BatchDurationNsec: conf.Sbft.BatchDurationNsec,
168+
BatchSizeBytes: conf.Sbft.BatchSizeBytes,
169+
RequestTimeoutNsec: conf.Sbft.RequestTimeoutNsec}
170+
peers := make(map[string][]byte)
171+
for addr, cert := range conf.Sbft.Peers {
172+
peers[addr], _ = sbftcrypto.ParseCertPEM(cert)
173+
}
174+
return &sbft.ConsensusConfig{Consensus: &cfg, Peers: peers}
175+
}
176+
177+
func makeSbftStackConfig(conf *config.TopLevel) *backend.StackConfig {
178+
return &backend.StackConfig{ListenAddr: conf.Sbft.PeerCommAddr,
179+
CertFile: conf.Sbft.CertFile,
180+
KeyFile: conf.Sbft.KeyFile,
181+
DataDir: conf.Sbft.DataDir}
182+
}

orderer/mocks/multichain/multichain.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ func (mcs *ConsenterSupport) WriteBlock(block *cb.Block, _committers []filter.Co
8383
umtxs[i] = utils.UnmarshalEnvelopeOrPanic(block.Data.Data[i])
8484
}
8585
mcs.Batches <- umtxs
86-
block.Metadata.Metadata[cb.BlockMetadataIndex_ORDERER] = utils.MarshalOrPanic(&cb.Metadata{Value: encodedMetadataValue})
86+
if encodedMetadataValue != nil {
87+
block.Metadata.Metadata[cb.BlockMetadataIndex_ORDERER] = utils.MarshalOrPanic(&cb.Metadata{Value: encodedMetadataValue})
88+
}
8789
mcs.WriteBlockVal = block
8890
return block
8991
}

0 commit comments

Comments
 (0)