Skip to content

Commit

Permalink
[FAB-666] orderer bootstrap from file
Browse files Browse the repository at this point in the history
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 <tdang@us.ibm.com>
  • Loading branch information
tuand27613 committed Jan 5, 2017
1 parent 4ad8f9e commit 7598dfe
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 2 deletions.
53 changes: 53 additions & 0 deletions orderer/common/bootstrap/file/bootstrap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
Copyright IBM Corp. 2016 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package file

import (
"fmt"
"io/ioutil"

"github.com/hyperledger/fabric/orderer/common/bootstrap"
cb "github.com/hyperledger/fabric/protos/common"

"github.com/golang/protobuf/proto"
)

type fileBootstrapper struct {
GenesisBlockFile string
}

// New returns a new static bootstrap helper
func New(fileName string) bootstrap.Helper {
return &fileBootstrapper{
GenesisBlockFile: fileName,
}
}

// GenesisBlock returns the genesis block to be used for bootstrapping
func (b *fileBootstrapper) GenesisBlock() *cb.Block {
bootstrapFile, fileErr := ioutil.ReadFile(b.GenesisBlockFile)
if fileErr != nil {
panic(fmt.Errorf("Unable to bootstrap orderer. Error reading genesis block file: %v", fileErr))
}
genesisBlock := &cb.Block{}
unmarshallErr := proto.Unmarshal(bootstrapFile, genesisBlock)
if unmarshallErr != nil {
panic(fmt.Errorf("Unable to bootstrap orderer. Error unmarshalling genesis block: %v", unmarshallErr))

}
return genesisBlock
} // GenesisBlock
102 changes: 102 additions & 0 deletions orderer/common/bootstrap/file/bootstrap_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
Copyright IBM Corp. 2016 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package file

import (
"bytes"
"os"
"testing"

"github.com/golang/protobuf/proto"
cb "github.com/hyperledger/fabric/protos/common"
)

const file = "./abc"

func TestNoFile(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Errorf("TestNoFile should have panicked")
}
}()

helper := New(file)
_ = helper.GenesisBlock()

} // TestNoFile

func TestBadBlock(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Errorf("TestBadBlock should have panicked")
}
}()

testFile, _ := os.Create(file)
defer os.Remove(file)
testFile.Write([]byte("abc"))
testFile.Close()
helper := New(file)
_ = helper.GenesisBlock()
} // TestBadBlock

func TestGenesisBlock(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Errorf("TestGenesisBlock: unexpected panic")
}
}()

header := &cb.BlockHeader{
Number: 0,
PreviousHash: nil,
DataHash: []byte("abc"),
}
data := &cb.BlockData{
Data: [][]byte{[]byte("abc")},
}
metadata := &cb.BlockMetadata{
Metadata: [][]byte{[]byte("abc")},
}
block := &cb.Block{
Header: header,
Data: data,
Metadata: metadata,
}
marshalledBlock, _ := proto.Marshal(block)

testFile, _ := os.Create(file)
defer os.Remove(file)
testFile.Write(marshalledBlock)
testFile.Close()

helper := New(file)
outBlock := helper.GenesisBlock()

outHeader := outBlock.Header
if outHeader.Number != 0 || outHeader.PreviousHash != nil || !bytes.Equal(outHeader.DataHash, []byte("abc")) {
t.Errorf("block header not read correctly. Got %+v\n . Should have been %+v\n", outHeader, header)
}
outData := outBlock.Data
if len(outData.Data) != 1 && !bytes.Equal(outData.Data[0], []byte("abc")) {
t.Errorf("block data not read correctly. Got %+v\n . Should have been %+v\n", outData, data)
}
outMeta := outBlock.Metadata
if len(outMeta.Metadata) != 1 && !bytes.Equal(outMeta.Metadata[0], []byte("abc")) {
t.Errorf("Metadata data not read correctly. Got %+v\n . Should have been %+v\n", outMeta, metadata)
}
} // TestGenesisBlock
4 changes: 4 additions & 0 deletions orderer/localconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type General struct {
ListenPort uint16
GenesisMethod string
BatchSize BatchSize
GenesisFile string
Profile Profile
}

Expand Down Expand Up @@ -112,6 +113,7 @@ var defaults = TopLevel{
BatchSize: BatchSize{
MaxMessageCount: 10,
},
GenesisFile: "./genesisblock",
Profile: Profile{
Enabled: false,
Address: "0.0.0.0:6060",
Expand Down Expand Up @@ -166,6 +168,8 @@ func (c *TopLevel) completeInitialization() {
c.General.ListenPort = defaults.General.ListenPort
case c.General.GenesisMethod == "":
c.General.GenesisMethod = defaults.General.GenesisMethod
case c.General.GenesisFile == "":
c.General.GenesisFile = defaults.General.GenesisFile
case c.General.Profile.Enabled && (c.General.Profile.Address == ""):
logger.Infof("Profiling enabled and General.Profile.Address unset, setting to %s", defaults.General.Profile.Address)
c.General.Profile.Address = defaults.General.Profile.Address
Expand Down
5 changes: 4 additions & 1 deletion orderer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"os"

"github.com/Shopify/sarama"
"github.com/hyperledger/fabric/orderer/common/bootstrap/file"
"github.com/hyperledger/fabric/orderer/common/bootstrap/provisional"
"github.com/hyperledger/fabric/orderer/kafka"
"github.com/hyperledger/fabric/orderer/localconfig"
Expand All @@ -36,8 +37,8 @@ import (
"github.com/hyperledger/fabric/orderer/solo"
cb "github.com/hyperledger/fabric/protos/common"
ab "github.com/hyperledger/fabric/protos/orderer"

"github.com/op/go-logging"

"google.golang.org/grpc"
)

Expand Down Expand Up @@ -73,6 +74,8 @@ func main() {
switch conf.General.GenesisMethod {
case "provisional":
genesisBlock = provisional.New(conf).GenesisBlock()
case "file":
genesisBlock = file.New(conf.General.GenesisFile).GenesisBlock()
default:
panic(fmt.Errorf("Unknown genesis method %s", conf.General.GenesisMethod))
}
Expand Down
5 changes: 4 additions & 1 deletion orderer/orderer.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,12 @@ General:
# Listen port: The port on which to bind to listen
ListenPort: 7050

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

# Genesis file: The file containing the genesis block. Used by the orderer when GenesisMethod is set to "file"
GenesisFile: ./genesisblock

# Enable an HTTP service for Go "pprof" profiling as documented at
# https://golang.org/pkg/net/http/pprof
Profile:
Expand Down

0 comments on commit 7598dfe

Please sign in to comment.