Skip to content

Commit db22cdc

Browse files
author
Jason Yellick
committed
Define orderer genesis block by config
The existing rawledger implementations have a hardcoded genesis block with non-sense data in it. In order to support bootstrapping in the future, this genesis block will need to contain meaningful data, and hardcoding its contents in the rawledgers is not a viable option. This changeset moves the static definition into a special static bootstrap helper package, and removes the references to the static genesis block from the rawledgers. Because the rawledgers now need an additional argument for construction, the effects are felt rippling through the tests, but the changes are fairly straightforward. This satisfies JIRA issue: https://jira.hyperledger.org/browse/FAB-688 Change-Id: I734a3215998c2977dd16e624869ceeb776767331 Signed-off-by: Jason Yellick <[email protected]>
1 parent 820ee67 commit db22cdc

13 files changed

+159
-28
lines changed

orderer/bootstrap/bootstrap.go

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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 bootstrap
18+
19+
import (
20+
ab "github.com/hyperledger/fabric/orderer/atomicbroadcast"
21+
)
22+
23+
// Helper defines the functions a bootstrapping implementation to provide
24+
type Helper interface {
25+
// GenesisBlock should return the genesis block required to bootstrap the ledger (be it reading from the filesystem, generating it, etc.)
26+
GenesisBlock() (*ab.Block, error)
27+
}

orderer/bootstrap/static/static.go

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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 static
18+
19+
import (
20+
ab "github.com/hyperledger/fabric/orderer/atomicbroadcast"
21+
"github.com/hyperledger/fabric/orderer/bootstrap"
22+
)
23+
24+
type bootstrapper struct{}
25+
26+
// New returns a new static bootstrap helper
27+
func New() bootstrap.Helper {
28+
return &bootstrapper{}
29+
}
30+
31+
// GenesisBlock returns the genesis block to be used for bootstrapping
32+
func (b *bootstrapper) GenesisBlock() (*ab.Block, error) {
33+
return &ab.Block{
34+
Number: 0,
35+
PrevHash: []byte("GENESIS"),
36+
}, nil
37+
38+
}

orderer/config/config.go

+4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ type General struct {
4747
MaxWindowSize uint
4848
ListenAddress string
4949
ListenPort uint16
50+
GenesisMethod string
5051
}
5152

5253
// RAMLedger contains config for the RAM ledger
@@ -97,6 +98,7 @@ var defaults = TopLevel{
9798
MaxWindowSize: 1000,
9899
ListenAddress: "127.0.0.1",
99100
ListenPort: 5151,
101+
GenesisMethod: "static",
100102
},
101103
RAMLedger: RAMLedger{
102104
HistorySize: 10000,
@@ -146,6 +148,8 @@ func (c *TopLevel) completeInitialization() {
146148
case c.General.ListenPort == 0:
147149
logger.Infof("General.ListenPort unset, setting to %s", defaults.General.ListenPort)
148150
c.General.ListenPort = defaults.General.ListenPort
151+
case c.General.GenesisMethod == "":
152+
c.General.GenesisMethod = defaults.General.GenesisMethod
149153
case c.FileLedger.Prefix == "":
150154
logger.Infof("FileLedger.Prefix unset, setting to %s", defaults.FileLedger.Prefix)
151155
c.FileLedger.Prefix = defaults.FileLedger.Prefix

orderer/main.go

+22-3
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,17 @@ import (
2525
"os"
2626
"os/signal"
2727

28-
"github.com/Shopify/sarama"
2928
ab "github.com/hyperledger/fabric/orderer/atomicbroadcast"
29+
"github.com/hyperledger/fabric/orderer/bootstrap"
30+
"github.com/hyperledger/fabric/orderer/bootstrap/static"
3031
"github.com/hyperledger/fabric/orderer/config"
3132
"github.com/hyperledger/fabric/orderer/kafka"
3233
"github.com/hyperledger/fabric/orderer/rawledger"
3334
"github.com/hyperledger/fabric/orderer/rawledger/fileledger"
3435
"github.com/hyperledger/fabric/orderer/rawledger/ramledger"
3536
"github.com/hyperledger/fabric/orderer/solo"
37+
38+
"github.com/Shopify/sarama"
3639
"google.golang.org/grpc"
3740
)
3841

@@ -58,6 +61,22 @@ func launchSolo(conf *config.TopLevel) {
5861
return
5962
}
6063

64+
var bootstrapper bootstrap.Helper
65+
66+
// Select the bootstrapping mechanism
67+
switch conf.General.GenesisMethod {
68+
case "static":
69+
bootstrapper = static.New()
70+
default:
71+
panic(fmt.Errorf("Unknown genesis method %s", conf.General.GenesisMethod))
72+
}
73+
74+
genesisBlock, err := bootstrapper.GenesisBlock()
75+
76+
if err != nil {
77+
panic(fmt.Errorf("Error retrieving the genesis block %s", err))
78+
}
79+
6180
// Stand in until real config
6281
ledgerType := os.Getenv("ORDERER_LEDGER_TYPE")
6382
var rawledger rawledger.ReadWriter
@@ -72,11 +91,11 @@ func launchSolo(conf *config.TopLevel) {
7291
}
7392
}
7493

75-
rawledger = fileledger.New(location)
94+
rawledger = fileledger.New(location, genesisBlock)
7695
case "ram":
7796
fallthrough
7897
default:
79-
rawledger = ramledger.New(int(conf.RAMLedger.HistorySize))
98+
rawledger = ramledger.New(int(conf.RAMLedger.HistorySize), genesisBlock)
8099
}
81100

82101
solo.New(int(conf.General.QueueSize), int(conf.General.BatchSize), int(conf.General.MaxWindowSize), conf.General.BatchTimeout, rawledger, grpcServer)

orderer/orderer.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ General:
3838
# Listen port: The port on which to bind to listen
3939
ListenPort: 5151
4040

41+
# Genesis method: The method by which to retrieve/generate the genesis block
42+
GenesisMethod: static
43+
4144
################################################################################
4245
#
4346
# SECTION: RAM Ledger

orderer/rawledger/fileledger/fileledger.go

+1-5
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ type fileLedger struct {
5454
}
5555

5656
// New creates a new instance of the file ledger
57-
func New(directory string) rawledger.ReadWriter {
57+
func New(directory string, genesisBlock *ab.Block) rawledger.ReadWriter {
5858
logger.Debugf("Initializing fileLedger at '%s'", directory)
5959
if err := os.MkdirAll(directory, 0700); err != nil {
6060
panic(err)
@@ -65,10 +65,6 @@ func New(directory string) rawledger.ReadWriter {
6565
signal: make(chan struct{}),
6666
marshaler: &jsonpb.Marshaler{Indent: " "},
6767
}
68-
genesisBlock := &ab.Block{
69-
Number: 0,
70-
PrevHash: []byte("GENESIS"),
71-
}
7268
if _, err := os.Stat(fl.blockFilename(genesisBlock.Number)); os.IsNotExist(err) {
7369
fl.writeBlock(genesisBlock)
7470
}

orderer/rawledger/fileledger/fileledger_test.go

+14-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,20 @@ import (
2323
"testing"
2424

2525
ab "github.com/hyperledger/fabric/orderer/atomicbroadcast"
26+
"github.com/hyperledger/fabric/orderer/bootstrap/static"
2627
)
2728

29+
var genesisBlock *ab.Block
30+
31+
func init() {
32+
bootstrapper := static.New()
33+
var err error
34+
genesisBlock, err = bootstrapper.GenesisBlock()
35+
if err != nil {
36+
panic("Error intializing static bootstrap genesis block")
37+
}
38+
}
39+
2840
type testEnv struct {
2941
t *testing.T
3042
location string
@@ -35,7 +47,7 @@ func initialize(t *testing.T) (*testEnv, *fileLedger) {
3547
if err != nil {
3648
t.Fatalf("Error creating temp dir: %s", err)
3749
}
38-
return &testEnv{location: name, t: t}, New(name).(*fileLedger)
50+
return &testEnv{location: name, t: t}, New(name, genesisBlock).(*fileLedger)
3951
}
4052

4153
func (tev *testEnv) tearDown() {
@@ -64,7 +76,7 @@ func TestReinitialization(t *testing.T) {
6476
tev, ofl := initialize(t)
6577
defer tev.tearDown()
6678
ofl.Append([]*ab.BroadcastMessage{&ab.BroadcastMessage{Data: []byte("My Data")}}, nil)
67-
fl := New(tev.location).(*fileLedger)
79+
fl := New(tev.location, genesisBlock).(*fileLedger)
6880
if fl.height != 2 {
6981
t.Fatalf("Block height should be 2")
7082
}

orderer/rawledger/fileledger_test.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,22 @@ import (
2020
"io/ioutil"
2121
"os"
2222

23+
ab "github.com/hyperledger/fabric/orderer/atomicbroadcast"
24+
"github.com/hyperledger/fabric/orderer/bootstrap/static"
2325
. "github.com/hyperledger/fabric/orderer/rawledger"
2426
"github.com/hyperledger/fabric/orderer/rawledger/fileledger"
2527
)
2628

29+
var genesisBlock *ab.Block
30+
2731
func init() {
32+
bootstrapper := static.New()
33+
var err error
34+
genesisBlock, err = bootstrapper.GenesisBlock()
35+
if err != nil {
36+
panic("Error intializing static bootstrap genesis block")
37+
}
38+
2839
testables = append(testables, &fileLedgerTestEnv{})
2940
}
3041

@@ -58,5 +69,5 @@ func (env *fileLedgerFactory) Persistent() bool {
5869
}
5970

6071
func (env *fileLedgerFactory) New() ReadWriter {
61-
return fileledger.New(env.location)
72+
return fileledger.New(env.location, genesisBlock)
6273
}

orderer/rawledger/ramledger/ramledger.go

+2-5
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,13 @@ type ramLedger struct {
4747
}
4848

4949
// New creates a new instance of the ram ledger
50-
func New(maxSize int) rawledger.ReadWriter {
50+
func New(maxSize int, genesis *ab.Block) rawledger.ReadWriter {
5151
rl := &ramLedger{
5252
maxSize: maxSize,
5353
size: 1,
5454
oldest: &simpleList{
5555
signal: make(chan struct{}),
56-
block: &ab.Block{
57-
Number: 0,
58-
PrevHash: []byte("GENESIS"),
59-
},
56+
block: genesis,
6057
},
6158
}
6259
rl.newest = rl.oldest

orderer/rawledger/ramledger/ramledger_test.go

+15-3
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,25 @@ import (
2020
"testing"
2121

2222
ab "github.com/hyperledger/fabric/orderer/atomicbroadcast"
23+
"github.com/hyperledger/fabric/orderer/bootstrap/static"
2324
)
2425

26+
var genesisBlock *ab.Block
27+
28+
func init() {
29+
bootstrapper := static.New()
30+
var err error
31+
genesisBlock, err = bootstrapper.GenesisBlock()
32+
if err != nil {
33+
panic("Error intializing static bootstrap genesis block")
34+
}
35+
}
36+
2537
// TestAppend ensures that appending blocks stores only the maxSize most recent blocks
2638
// Note that 'only' is applicable because the genesis block will be discarded
2739
func TestAppend(t *testing.T) {
2840
maxSize := 3
29-
rl := New(maxSize).(*ramLedger)
41+
rl := New(maxSize, genesisBlock).(*ramLedger)
3042
var blocks []*ab.Block
3143
for i := 0; i < 3; i++ {
3244
blocks = append(blocks, &ab.Block{Number: uint64(i + 1)})
@@ -51,7 +63,7 @@ func TestAppend(t *testing.T) {
5163
// TestSignal checks if the signal channel closes when an item is appended
5264
func TestSignal(t *testing.T) {
5365
maxSize := 3
54-
rl := New(maxSize).(*ramLedger)
66+
rl := New(maxSize, genesisBlock).(*ramLedger)
5567
item := rl.newest
5668
select {
5769
case <-item.signal:
@@ -72,7 +84,7 @@ func TestSignal(t *testing.T) {
7284
func TestTruncationSafety(t *testing.T) {
7385
maxSize := 3
7486
newBlocks := 10
75-
rl := New(maxSize).(*ramLedger)
87+
rl := New(maxSize, genesisBlock).(*ramLedger)
7688
item := rl.oldest
7789
for i := 0; i < newBlocks; i++ {
7890
rl.appendBlock(&ab.Block{Number: uint64(i + 1)})

orderer/rawledger/ramledger_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,5 @@ func (env *ramLedgerFactory) Persistent() bool {
4747

4848
func (env *ramLedgerFactory) New() ReadWriter {
4949
historySize := 10
50-
return ramledger.New(historySize)
50+
return ramledger.New(historySize, genesisBlock)
5151
}

orderer/solo/broadcast_test.go

+14-2
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,22 @@ import (
2424
"google.golang.org/grpc"
2525

2626
ab "github.com/hyperledger/fabric/orderer/atomicbroadcast"
27+
"github.com/hyperledger/fabric/orderer/bootstrap/static"
2728
"github.com/hyperledger/fabric/orderer/rawledger"
2829
"github.com/hyperledger/fabric/orderer/rawledger/ramledger"
2930
)
3031

32+
var genesisBlock *ab.Block
33+
34+
func init() {
35+
bootstrapper := static.New()
36+
var err error
37+
genesisBlock, err = bootstrapper.GenesisBlock()
38+
if err != nil {
39+
panic("Error intializing static bootstrap genesis block")
40+
}
41+
}
42+
3143
type mockB struct {
3244
grpc.ServerStream
3345
recvChan chan *ab.BroadcastMessage
@@ -124,7 +136,7 @@ func TestEmptyBroadcastMessage(t *testing.T) {
124136
}
125137

126138
func TestEmptyBatch(t *testing.T) {
127-
bs := newPlainBroadcastServer(2, 1, time.Millisecond, ramledger.New(10))
139+
bs := newPlainBroadcastServer(2, 1, time.Millisecond, ramledger.New(10, genesisBlock))
128140
time.Sleep(100 * time.Millisecond) // Note, this is not a race, as worst case, the timer does not expire, and the test still passes
129141
if bs.rl.(rawledger.Reader).Height() != 1 {
130142
t.Fatalf("Expected no new blocks created")
@@ -133,7 +145,7 @@ func TestEmptyBatch(t *testing.T) {
133145

134146
func TestFilledBatch(t *testing.T) {
135147
batchSize := 2
136-
bs := newBroadcastServer(0, batchSize, time.Hour, ramledger.New(10))
148+
bs := newBroadcastServer(0, batchSize, time.Hour, ramledger.New(10, genesisBlock))
137149
defer bs.halt()
138150
messages := 11 // Sending 11 messages, with a batch size of 2, ensures the 10th message is processed before we proceed for 5 blocks
139151
for i := 0; i < messages; i++ {

0 commit comments

Comments
 (0)