Skip to content

Commit c883319

Browse files
author
Jason Yellick
committed
Hook config and policy pieces into orderer startup
This changeset takes the existing work of the config manager, policy manager, and static genesis block creation and hooks them together into the main execution path. Note that the configuration manager is not utilized for any configuration and there is no policy enforcement for chain modifications, so this is only a half step, and will be followed by utilization of the config manager and enforcement of policy on new transactions. Note also, that this changeset does not include tests by design, as it is merely referencing existing pieces of tested code and adds no new function itself. All errors in this code path result in panic so the bdd tests cover it as well. Change-Id: Ie7f67971fee6c223378612af727e8f9aeca0e48e Signed-off-by: Jason Yellick <[email protected]>
1 parent 4db9abf commit c883319

File tree

2 files changed

+139
-2
lines changed

2 files changed

+139
-2
lines changed

orderer/common/bootstrap/static/static.go

+62-2
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,82 @@ limitations under the License.
1717
package static
1818

1919
import (
20+
"math/rand"
21+
2022
ab "github.com/hyperledger/fabric/orderer/atomicbroadcast"
2123
"github.com/hyperledger/fabric/orderer/common/bootstrap"
24+
"github.com/hyperledger/fabric/orderer/common/cauthdsl"
25+
"github.com/hyperledger/fabric/orderer/common/configtx"
26+
27+
"github.com/golang/protobuf/proto"
2228
)
2329

24-
type bootstrapper struct{}
30+
type bootstrapper struct {
31+
chainID []byte
32+
}
2533

2634
// New returns a new static bootstrap helper
2735
func New() bootstrap.Helper {
28-
return &bootstrapper{}
36+
b := make([]byte, 16)
37+
rand.Read(b)
38+
39+
return &bootstrapper{
40+
chainID: b,
41+
}
42+
}
43+
44+
// errorlessMarshal prevents poluting this code with many panics, if the genesis block cannot be created, the system cannot start so panic is correct
45+
func errorlessMarshal(thing proto.Message) []byte {
46+
data, err := proto.Marshal(thing)
47+
if err != nil {
48+
panic(err)
49+
}
50+
return data
51+
}
52+
53+
func (b *bootstrapper) makeConfigurationEntry(id string, ctype ab.Configuration_ConfigurationType, data []byte, modificationPolicyID string) *ab.ConfigurationEntry {
54+
configurationBytes := errorlessMarshal(&ab.Configuration{
55+
ChainID: b.chainID,
56+
ID: id,
57+
LastModified: 0,
58+
Type: ctype,
59+
Data: data,
60+
ModificationPolicy: modificationPolicyID,
61+
})
62+
return &ab.ConfigurationEntry{
63+
Configuration: configurationBytes,
64+
}
65+
}
66+
67+
func sigPolicyToPolicy(sigPolicy *ab.SignaturePolicyEnvelope) []byte {
68+
policy := &ab.Policy{
69+
Type: &ab.Policy_SignaturePolicy{
70+
SignaturePolicy: sigPolicy,
71+
},
72+
}
73+
return errorlessMarshal(policy)
2974
}
3075

3176
// GenesisBlock returns the genesis block to be used for bootstrapping
3277
func (b *bootstrapper) GenesisBlock() (*ab.Block, error) {
78+
79+
// Lock down the default modification policy to prevent any further policy modifications
80+
lockdownDefaultModificationPolicy := b.makeConfigurationEntry(configtx.DefaultModificationPolicyID, ab.Configuration_Policy, sigPolicyToPolicy(cauthdsl.RejectAllPolicy), configtx.DefaultModificationPolicyID)
81+
82+
initialConfigTX := errorlessMarshal(&ab.ConfigurationEnvelope{
83+
Sequence: 0,
84+
ChainID: b.chainID,
85+
Entries: []*ab.ConfigurationEntry{
86+
lockdownDefaultModificationPolicy,
87+
},
88+
})
89+
3390
return &ab.Block{
3491
Number: 0,
3592
PrevHash: []byte("GENESIS"),
93+
Messages: []*ab.BroadcastMessage{
94+
&ab.BroadcastMessage{Data: initialConfigTX},
95+
},
3696
}, nil
3797

3898
}

orderer/main.go

+77
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import (
2828
ab "github.com/hyperledger/fabric/orderer/atomicbroadcast"
2929
"github.com/hyperledger/fabric/orderer/common/bootstrap"
3030
"github.com/hyperledger/fabric/orderer/common/bootstrap/static"
31+
"github.com/hyperledger/fabric/orderer/common/configtx"
32+
"github.com/hyperledger/fabric/orderer/common/policies"
3133
"github.com/hyperledger/fabric/orderer/config"
3234
"github.com/hyperledger/fabric/orderer/kafka"
3335
"github.com/hyperledger/fabric/orderer/rawledger"
@@ -36,6 +38,8 @@ import (
3638
"github.com/hyperledger/fabric/orderer/solo"
3739

3840
"github.com/Shopify/sarama"
41+
"github.com/golang/protobuf/proto"
42+
"github.com/op/go-logging"
3943
"google.golang.org/grpc"
4044
)
4145

@@ -52,6 +56,69 @@ func main() {
5256
}
5357
}
5458

59+
// XXX This crypto helper is a stand in until we have a real crypto handler
60+
// it considers all signatures to be valid
61+
type xxxCryptoHelper struct{}
62+
63+
func (xxx xxxCryptoHelper) VerifySignature(msg []byte, ids []byte, sigs []byte) bool {
64+
return true
65+
}
66+
67+
func init() {
68+
logging.SetLevel(logging.DEBUG, "")
69+
}
70+
71+
func retrieveConfiguration(rl rawledger.Reader) *ab.ConfigurationEnvelope {
72+
var lastConfigTx *ab.ConfigurationEnvelope
73+
74+
it, _ := rl.Iterator(ab.SeekInfo_OLDEST, 0)
75+
// Iterate over the blockchain, looking for config transactions, track the most recent one encountered
76+
// this will be the transaction which is returned
77+
for {
78+
select {
79+
case <-it.ReadyChan():
80+
block, status := it.Next()
81+
if status != ab.Status_SUCCESS {
82+
panic(fmt.Errorf("Error parsing blockchain at startup: %v", status))
83+
}
84+
// ConfigTxs should always be by themselves
85+
if len(block.Messages) != 1 {
86+
continue
87+
}
88+
89+
maybeConfigTx := &ab.ConfigurationEnvelope{}
90+
91+
err := proto.Unmarshal(block.Messages[0].Data, maybeConfigTx)
92+
93+
if err == nil {
94+
lastConfigTx = maybeConfigTx
95+
}
96+
default:
97+
return lastConfigTx
98+
}
99+
}
100+
}
101+
102+
func bootstrapConfigManager(lastConfigTx *ab.ConfigurationEnvelope) configtx.Manager {
103+
policyManager := policies.NewManagerImpl(xxxCryptoHelper{})
104+
configHandlerMap := make(map[ab.Configuration_ConfigurationType]configtx.Handler)
105+
for ctype := range ab.Configuration_ConfigurationType_name {
106+
rtype := ab.Configuration_ConfigurationType(ctype)
107+
switch rtype {
108+
case ab.Configuration_Policy:
109+
configHandlerMap[rtype] = policyManager
110+
default:
111+
configHandlerMap[rtype] = configtx.NewBytesHandler()
112+
}
113+
}
114+
115+
configManager, err := configtx.NewConfigurationManager(lastConfigTx, policyManager, configHandlerMap)
116+
if err != nil {
117+
panic(err)
118+
}
119+
return configManager
120+
}
121+
55122
func launchSolo(conf *config.TopLevel) {
56123
grpcServer := grpc.NewServer()
57124

@@ -98,6 +165,16 @@ func launchSolo(conf *config.TopLevel) {
98165
rawledger = ramledger.New(int(conf.RAMLedger.HistorySize), genesisBlock)
99166
}
100167

168+
lastConfigTx := retrieveConfiguration(rawledger)
169+
if lastConfigTx == nil {
170+
panic("No chain configuration found")
171+
}
172+
173+
configManager := bootstrapConfigManager(lastConfigTx)
174+
175+
// XXX actually use the config manager in the future
176+
_ = configManager
177+
101178
solo.New(int(conf.General.QueueSize), int(conf.General.BatchSize), int(conf.General.MaxWindowSize), conf.General.BatchTimeout, rawledger, grpcServer)
102179
grpcServer.Serve(lis)
103180
}

0 commit comments

Comments
 (0)