Skip to content

Commit

Permalink
Hook config and policy pieces into orderer startup
Browse files Browse the repository at this point in the history
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 <jyellick@us.ibm.com>
  • Loading branch information
Jason Yellick committed Oct 26, 2016
1 parent 4db9abf commit c883319
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 2 deletions.
64 changes: 62 additions & 2 deletions orderer/common/bootstrap/static/static.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,82 @@ limitations under the License.
package static

import (
"math/rand"

ab "github.com/hyperledger/fabric/orderer/atomicbroadcast"
"github.com/hyperledger/fabric/orderer/common/bootstrap"
"github.com/hyperledger/fabric/orderer/common/cauthdsl"
"github.com/hyperledger/fabric/orderer/common/configtx"

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

type bootstrapper struct{}
type bootstrapper struct {
chainID []byte
}

// New returns a new static bootstrap helper
func New() bootstrap.Helper {
return &bootstrapper{}
b := make([]byte, 16)
rand.Read(b)

return &bootstrapper{
chainID: b,
}
}

// errorlessMarshal prevents poluting this code with many panics, if the genesis block cannot be created, the system cannot start so panic is correct
func errorlessMarshal(thing proto.Message) []byte {
data, err := proto.Marshal(thing)
if err != nil {
panic(err)
}
return data
}

func (b *bootstrapper) makeConfigurationEntry(id string, ctype ab.Configuration_ConfigurationType, data []byte, modificationPolicyID string) *ab.ConfigurationEntry {
configurationBytes := errorlessMarshal(&ab.Configuration{
ChainID: b.chainID,
ID: id,
LastModified: 0,
Type: ctype,
Data: data,
ModificationPolicy: modificationPolicyID,
})
return &ab.ConfigurationEntry{
Configuration: configurationBytes,
}
}

func sigPolicyToPolicy(sigPolicy *ab.SignaturePolicyEnvelope) []byte {
policy := &ab.Policy{
Type: &ab.Policy_SignaturePolicy{
SignaturePolicy: sigPolicy,
},
}
return errorlessMarshal(policy)
}

// GenesisBlock returns the genesis block to be used for bootstrapping
func (b *bootstrapper) GenesisBlock() (*ab.Block, error) {

// Lock down the default modification policy to prevent any further policy modifications
lockdownDefaultModificationPolicy := b.makeConfigurationEntry(configtx.DefaultModificationPolicyID, ab.Configuration_Policy, sigPolicyToPolicy(cauthdsl.RejectAllPolicy), configtx.DefaultModificationPolicyID)

initialConfigTX := errorlessMarshal(&ab.ConfigurationEnvelope{
Sequence: 0,
ChainID: b.chainID,
Entries: []*ab.ConfigurationEntry{
lockdownDefaultModificationPolicy,
},
})

return &ab.Block{
Number: 0,
PrevHash: []byte("GENESIS"),
Messages: []*ab.BroadcastMessage{
&ab.BroadcastMessage{Data: initialConfigTX},
},
}, nil

}
77 changes: 77 additions & 0 deletions orderer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import (
ab "github.com/hyperledger/fabric/orderer/atomicbroadcast"
"github.com/hyperledger/fabric/orderer/common/bootstrap"
"github.com/hyperledger/fabric/orderer/common/bootstrap/static"
"github.com/hyperledger/fabric/orderer/common/configtx"
"github.com/hyperledger/fabric/orderer/common/policies"
"github.com/hyperledger/fabric/orderer/config"
"github.com/hyperledger/fabric/orderer/kafka"
"github.com/hyperledger/fabric/orderer/rawledger"
Expand All @@ -36,6 +38,8 @@ import (
"github.com/hyperledger/fabric/orderer/solo"

"github.com/Shopify/sarama"
"github.com/golang/protobuf/proto"
"github.com/op/go-logging"
"google.golang.org/grpc"
)

Expand All @@ -52,6 +56,69 @@ func main() {
}
}

// XXX This crypto helper is a stand in until we have a real crypto handler
// it considers all signatures to be valid
type xxxCryptoHelper struct{}

func (xxx xxxCryptoHelper) VerifySignature(msg []byte, ids []byte, sigs []byte) bool {
return true
}

func init() {
logging.SetLevel(logging.DEBUG, "")
}

func retrieveConfiguration(rl rawledger.Reader) *ab.ConfigurationEnvelope {
var lastConfigTx *ab.ConfigurationEnvelope

it, _ := rl.Iterator(ab.SeekInfo_OLDEST, 0)
// Iterate over the blockchain, looking for config transactions, track the most recent one encountered
// this will be the transaction which is returned
for {
select {
case <-it.ReadyChan():
block, status := it.Next()
if status != ab.Status_SUCCESS {
panic(fmt.Errorf("Error parsing blockchain at startup: %v", status))
}
// ConfigTxs should always be by themselves
if len(block.Messages) != 1 {
continue
}

maybeConfigTx := &ab.ConfigurationEnvelope{}

err := proto.Unmarshal(block.Messages[0].Data, maybeConfigTx)

if err == nil {
lastConfigTx = maybeConfigTx
}
default:
return lastConfigTx
}
}
}

func bootstrapConfigManager(lastConfigTx *ab.ConfigurationEnvelope) configtx.Manager {
policyManager := policies.NewManagerImpl(xxxCryptoHelper{})
configHandlerMap := make(map[ab.Configuration_ConfigurationType]configtx.Handler)
for ctype := range ab.Configuration_ConfigurationType_name {
rtype := ab.Configuration_ConfigurationType(ctype)
switch rtype {
case ab.Configuration_Policy:
configHandlerMap[rtype] = policyManager
default:
configHandlerMap[rtype] = configtx.NewBytesHandler()
}
}

configManager, err := configtx.NewConfigurationManager(lastConfigTx, policyManager, configHandlerMap)
if err != nil {
panic(err)
}
return configManager
}

func launchSolo(conf *config.TopLevel) {
grpcServer := grpc.NewServer()

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

lastConfigTx := retrieveConfiguration(rawledger)
if lastConfigTx == nil {
panic("No chain configuration found")
}

configManager := bootstrapConfigManager(lastConfigTx)

// XXX actually use the config manager in the future
_ = configManager

solo.New(int(conf.General.QueueSize), int(conf.General.BatchSize), int(conf.General.MaxWindowSize), conf.General.BatchTimeout, rawledger, grpcServer)
grpcServer.Serve(lis)
}
Expand Down

0 comments on commit c883319

Please sign in to comment.