Skip to content

Commit 7598dfe

Browse files
committed
[FAB-666] orderer bootstrap from file
Set general.GenesisMethod and general.GenesisFile in the orderer.yaml file to bootstrap the orderer by reading the genesis block from a file This is a continuation of https://gerrit.hyperledger.org/r/#/c/2605 01/05/2017 rebase to latest master Change-Id: I42b971ef77de2f7d8830e369d4464c961bed6ef4 Signed-off-by: tuand27613 <[email protected]>
1 parent 4ad8f9e commit 7598dfe

File tree

5 files changed

+167
-2
lines changed

5 files changed

+167
-2
lines changed
+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
Copyright IBM Corp. 2016 All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package file
18+
19+
import (
20+
"fmt"
21+
"io/ioutil"
22+
23+
"github.com/hyperledger/fabric/orderer/common/bootstrap"
24+
cb "github.com/hyperledger/fabric/protos/common"
25+
26+
"github.com/golang/protobuf/proto"
27+
)
28+
29+
type fileBootstrapper struct {
30+
GenesisBlockFile string
31+
}
32+
33+
// New returns a new static bootstrap helper
34+
func New(fileName string) bootstrap.Helper {
35+
return &fileBootstrapper{
36+
GenesisBlockFile: fileName,
37+
}
38+
}
39+
40+
// GenesisBlock returns the genesis block to be used for bootstrapping
41+
func (b *fileBootstrapper) GenesisBlock() *cb.Block {
42+
bootstrapFile, fileErr := ioutil.ReadFile(b.GenesisBlockFile)
43+
if fileErr != nil {
44+
panic(fmt.Errorf("Unable to bootstrap orderer. Error reading genesis block file: %v", fileErr))
45+
}
46+
genesisBlock := &cb.Block{}
47+
unmarshallErr := proto.Unmarshal(bootstrapFile, genesisBlock)
48+
if unmarshallErr != nil {
49+
panic(fmt.Errorf("Unable to bootstrap orderer. Error unmarshalling genesis block: %v", unmarshallErr))
50+
51+
}
52+
return genesisBlock
53+
} // GenesisBlock
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
Copyright IBM Corp. 2016 All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package file
18+
19+
import (
20+
"bytes"
21+
"os"
22+
"testing"
23+
24+
"github.com/golang/protobuf/proto"
25+
cb "github.com/hyperledger/fabric/protos/common"
26+
)
27+
28+
const file = "./abc"
29+
30+
func TestNoFile(t *testing.T) {
31+
defer func() {
32+
if r := recover(); r == nil {
33+
t.Errorf("TestNoFile should have panicked")
34+
}
35+
}()
36+
37+
helper := New(file)
38+
_ = helper.GenesisBlock()
39+
40+
} // TestNoFile
41+
42+
func TestBadBlock(t *testing.T) {
43+
defer func() {
44+
if r := recover(); r == nil {
45+
t.Errorf("TestBadBlock should have panicked")
46+
}
47+
}()
48+
49+
testFile, _ := os.Create(file)
50+
defer os.Remove(file)
51+
testFile.Write([]byte("abc"))
52+
testFile.Close()
53+
helper := New(file)
54+
_ = helper.GenesisBlock()
55+
} // TestBadBlock
56+
57+
func TestGenesisBlock(t *testing.T) {
58+
defer func() {
59+
if r := recover(); r != nil {
60+
t.Errorf("TestGenesisBlock: unexpected panic")
61+
}
62+
}()
63+
64+
header := &cb.BlockHeader{
65+
Number: 0,
66+
PreviousHash: nil,
67+
DataHash: []byte("abc"),
68+
}
69+
data := &cb.BlockData{
70+
Data: [][]byte{[]byte("abc")},
71+
}
72+
metadata := &cb.BlockMetadata{
73+
Metadata: [][]byte{[]byte("abc")},
74+
}
75+
block := &cb.Block{
76+
Header: header,
77+
Data: data,
78+
Metadata: metadata,
79+
}
80+
marshalledBlock, _ := proto.Marshal(block)
81+
82+
testFile, _ := os.Create(file)
83+
defer os.Remove(file)
84+
testFile.Write(marshalledBlock)
85+
testFile.Close()
86+
87+
helper := New(file)
88+
outBlock := helper.GenesisBlock()
89+
90+
outHeader := outBlock.Header
91+
if outHeader.Number != 0 || outHeader.PreviousHash != nil || !bytes.Equal(outHeader.DataHash, []byte("abc")) {
92+
t.Errorf("block header not read correctly. Got %+v\n . Should have been %+v\n", outHeader, header)
93+
}
94+
outData := outBlock.Data
95+
if len(outData.Data) != 1 && !bytes.Equal(outData.Data[0], []byte("abc")) {
96+
t.Errorf("block data not read correctly. Got %+v\n . Should have been %+v\n", outData, data)
97+
}
98+
outMeta := outBlock.Metadata
99+
if len(outMeta.Metadata) != 1 && !bytes.Equal(outMeta.Metadata[0], []byte("abc")) {
100+
t.Errorf("Metadata data not read correctly. Got %+v\n . Should have been %+v\n", outMeta, metadata)
101+
}
102+
} // TestGenesisBlock

orderer/localconfig/config.go

+4
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ type General struct {
4848
ListenPort uint16
4949
GenesisMethod string
5050
BatchSize BatchSize
51+
GenesisFile string
5152
Profile Profile
5253
}
5354

@@ -112,6 +113,7 @@ var defaults = TopLevel{
112113
BatchSize: BatchSize{
113114
MaxMessageCount: 10,
114115
},
116+
GenesisFile: "./genesisblock",
115117
Profile: Profile{
116118
Enabled: false,
117119
Address: "0.0.0.0:6060",
@@ -166,6 +168,8 @@ func (c *TopLevel) completeInitialization() {
166168
c.General.ListenPort = defaults.General.ListenPort
167169
case c.General.GenesisMethod == "":
168170
c.General.GenesisMethod = defaults.General.GenesisMethod
171+
case c.General.GenesisFile == "":
172+
c.General.GenesisFile = defaults.General.GenesisFile
169173
case c.General.Profile.Enabled && (c.General.Profile.Address == ""):
170174
logger.Infof("Profiling enabled and General.Profile.Address unset, setting to %s", defaults.General.Profile.Address)
171175
c.General.Profile.Address = defaults.General.Profile.Address

orderer/main.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"os"
2727

2828
"github.com/Shopify/sarama"
29+
"github.com/hyperledger/fabric/orderer/common/bootstrap/file"
2930
"github.com/hyperledger/fabric/orderer/common/bootstrap/provisional"
3031
"github.com/hyperledger/fabric/orderer/kafka"
3132
"github.com/hyperledger/fabric/orderer/localconfig"
@@ -36,8 +37,8 @@ import (
3637
"github.com/hyperledger/fabric/orderer/solo"
3738
cb "github.com/hyperledger/fabric/protos/common"
3839
ab "github.com/hyperledger/fabric/protos/orderer"
39-
4040
"github.com/op/go-logging"
41+
4142
"google.golang.org/grpc"
4243
)
4344

@@ -73,6 +74,8 @@ func main() {
7374
switch conf.General.GenesisMethod {
7475
case "provisional":
7576
genesisBlock = provisional.New(conf).GenesisBlock()
77+
case "file":
78+
genesisBlock = file.New(conf.General.GenesisFile).GenesisBlock()
7679
default:
7780
panic(fmt.Errorf("Unknown genesis method %s", conf.General.GenesisMethod))
7881
}

orderer/orderer.yaml

+4-1
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,12 @@ General:
4040
# Listen port: The port on which to bind to listen
4141
ListenPort: 7050
4242

43-
# Genesis method: The method by which to retrieve/generate the genesis block
43+
# Genesis method: The method by which to retrieve/generate the genesis block. Available values are "provisional", "file"
4444
GenesisMethod: provisional
4545

46+
# Genesis file: The file containing the genesis block. Used by the orderer when GenesisMethod is set to "file"
47+
GenesisFile: ./genesisblock
48+
4649
# Enable an HTTP service for Go "pprof" profiling as documented at
4750
# https://golang.org/pkg/net/http/pprof
4851
Profile:

0 commit comments

Comments
 (0)