Skip to content

Commit

Permalink
MSP mgr instantiation from Block
Browse files Browse the repository at this point in the history
This change-set introduces a proper implementation of the function that
generates an MSP manager out of a Block from the ledger. We expect one
ConfigurationItem per MSP, each containing in the Value field the protobuf
serialization of an MSPConfig message. The MSP config schema has been further
simplified by removing the MSPManagerConfig struct. Furthermore, MSP's and
MSPManager's are now immutable types: the reconfig method has been removed and
reconfiguring a manager/msp means constructing a new one and letting the old
instance go out of scope.

Change-Id: I42b12e1bece4084ab5695f60050ce512a5286e87
Signed-off-by: Alessandro Sorniotti <ale.linux@sopit.net>
  • Loading branch information
ale-linux committed Dec 14, 2016
1 parent 4c63856 commit 6444545
Show file tree
Hide file tree
Showing 16 changed files with 475 additions and 259 deletions.
2 changes: 1 addition & 1 deletion core/peer/msgvalidation.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func checkSignatureFromCreator(creatorBytes []byte, sig []byte, msg []byte, Chai
putilsLogger.Infof("checkSignatureFromCreator info: creator is %s", creator.GetIdentifier())

// ensure that creator is a valid certificate
err = creator.IsValid()
err = creator.Validate()
if err != nil {
return fmt.Errorf("The creator certificate is not valid, err %s", err)
}
Expand Down
39 changes: 10 additions & 29 deletions core/peer/msp/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"github.com/hyperledger/fabric/core/util"
"github.com/hyperledger/fabric/msp"
"github.com/hyperledger/fabric/protos/common"
mspprotos "github.com/hyperledger/fabric/protos/msp"
"github.com/hyperledger/fabric/protos/msp/utils"
)

func LoadLocalMsp(dir string) error {
Expand All @@ -30,7 +32,7 @@ func LoadFakeSetupWithLocalMspAndTestChainMsp(dir string) error {
return err
}

fakeConfig = &msp.MSPManagerConfig{MspList: []*msp.MSPConfig{conf}, Name: "MGRFORTESTCHAIN"}
fakeConfig := []*mspprotos.MSPConfig{conf}

err = GetManagerForChain(util.GetTestChainID()).Setup(fakeConfig)
if err != nil {
Expand All @@ -40,39 +42,18 @@ func LoadFakeSetupWithLocalMspAndTestChainMsp(dir string) error {
return nil
}

// FIXME! Every chain needs an MSP config but for now,
// we don't have support for that; we get around it
// temporarily by storing the config the peer loaded
// and using it every time we're asked to get an MSP
// manager via LoadMSPManagerFromBlock
var fakeConfig *msp.MSPManagerConfig

// GetMSPManagerFromBlock returns a new MSP manager from a ConfigurationEnvelope
func GetMSPManagerFromBlock(b *common.Block) (msp.MSPManager, error) {
// FIXME! We need to extract the config item
// that relates to MSP from the contig tx
// inside this block, unmarshal it to extract
// an *MSPManagerConfig that we can then pass
// to the Setup method; for now we wing it by
// passing the same config we got for the
// local manager; this way chain creation tests
// can proceed without being block by this

// this hack is required to give us some configuration
// so that we can return a valid MSP manager when
// someone calls this function; it should work, provided
// that this call occurs after the peer has started
// and called LoadFakeSetupWithLocalMspAndTestChainMsp.
// Notice that this happens very early in the peer
// startup and so the assumption should be safe
if fakeConfig == nil {
panic("fakeConfig is nil")
mgrConfig, err := msputils.GetMSPManagerConfigFromBlock(b)
if err != nil {
return nil, err
}

mgr := msp.NewMSPManager()
err := mgr.Setup(fakeConfig)
err = mgr.Setup(mgrConfig)
if err != nil {
return nil, err
} else {
return mgr, nil
}

return mgr, nil
}
15 changes: 10 additions & 5 deletions core/peer/msp/peermsp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import (
"testing"

"github.com/hyperledger/fabric/core/util"
"github.com/hyperledger/fabric/protos/common"
"github.com/hyperledger/fabric/msp"
"github.com/hyperledger/fabric/protos/msp/testutils"
)

func TestLocalMSP(t *testing.T) {
Expand Down Expand Up @@ -41,14 +42,18 @@ func TestFakeSetup(t *testing.T) {
}
}

// TODO: as soon as proper per-chain MSP support is developed, this test will have to be changed
func TestGetMSPManagerFromBlock(t *testing.T) {
err := LoadLocalMsp("../../../msp/sampleconfig/")
conf, err := msp.GetLocalMspConfig("../../../msp/sampleconfig/")
if err != nil {
t.Fatalf("LoadLocalMsp failed, err %s", err)
t.Fatalf("GetLocalMspConfig failed, err %s", err)
}

block, err := msptestutils.GetTestBlockFromMspConfig(conf)
if err != nil {
t.Fatalf("getTestBlockFromMspConfig failed, err %s", err)
}

mgr, err := GetMSPManagerFromBlock(&common.Block{ /* TODO: FILLME! */ })
mgr, err := GetMSPManagerFromBlock(block)
if err != nil {
t.Fatalf("GetMSPManagerFromBlock failed, err %s", err)
} else if mgr == nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ func validateProposalResponse(prBytes []byte, proposal *pb.Proposal, visibility
}

// ensure that endorser has a valid certificate
err = endorser.IsValid()
err = endorser.Validate()
if err != nil {
return fmt.Errorf("The endorser certificate is not valid, err %s", err)
}
Expand Down
2 changes: 1 addition & 1 deletion core/system_chaincode/vscc/validator_onevalidsignature.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func (vscc *ValidatorOneValidSignature) Invoke(stub shim.ChaincodeStubInterface)
}

// validate it
err = end.IsValid()
err = end.Validate()
if err != nil {
return nil, fmt.Errorf("Invalid endorser identity, err %s", err)
}
Expand Down
14 changes: 8 additions & 6 deletions msp/configbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (

"encoding/pem"
"path/filepath"

"github.com/hyperledger/fabric/protos/msp"
)

func readFile(file string) ([]byte, error) {
Expand Down Expand Up @@ -46,7 +48,7 @@ func getPemMaterialFromDir(dir string) ([][]byte, error) {
continue
}

fullName := dir + string(filepath.Separator) + f.Name()
fullName := filepath.Join(dir, string(filepath.Separator), f.Name())
mspLogger.Infof("Inspecting file %s", fullName)

item, err := readPemFile(fullName)
Expand All @@ -67,7 +69,7 @@ const (
keystore = "keystore"
)

func GetLocalMspConfig(dir string) (*MSPConfig, error) {
func GetLocalMspConfig(dir string) (*msp.MSPConfig, error) {
cacertDir := dir + string(filepath.Separator) + cacerts
signcertDir := dir + string(filepath.Separator) + signcerts
admincertDir := dir + string(filepath.Separator) + admincerts
Expand Down Expand Up @@ -98,15 +100,15 @@ func GetLocalMspConfig(dir string) (*MSPConfig, error) {
// 2) there is exactly one signing key
// 3) the cert and the key match

keyinfo := &KeyInfo{KeyIdentifier: "PEER", KeyMaterial: keys[0]}
keyinfo := &msp.KeyInfo{KeyIdentifier: "PEER", KeyMaterial: keys[0]}

sigid := &SigningIdentityInfo{PublicSigner: signcert[0], PrivateSigner: keyinfo}
sigid := &msp.SigningIdentityInfo{PublicSigner: signcert[0], PrivateSigner: keyinfo}

fmspconf := FabricMSPConfig{Admins: admincert, RootCerts: cacerts, SigningIdentity: sigid, Name: "DEFAULT"}
fmspconf := msp.FabricMSPConfig{Admins: admincert, RootCerts: cacerts, SigningIdentity: sigid, Name: "DEFAULT"}

fmpsjs, _ := json.Marshal(fmspconf)

mspconf := &MSPConfig{Config: fmpsjs, Type: FABRIC}
mspconf := &msp.MSPConfig{Config: fmpsjs, Type: int32(FABRIC)}

return mspconf, nil
}
2 changes: 1 addition & 1 deletion msp/identities.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (id *identity) GetMSPIdentifier() string {
}

// IsValid returns nil if this instance is a valid identity or an error otherwise
func (id *identity) IsValid() error {
func (id *identity) Validate() error {
return id.msp.Validate(id)
}

Expand Down
56 changes: 20 additions & 36 deletions msp/msp.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ limitations under the License.

package msp

import "github.com/hyperledger/fabric/protos/msp"

// FIXME: we need better comments on the interfaces!!
// FIXME: we need better comments on the interfaces!!
// FIXME: we need better comments on the interfaces!!

// Membership service provider APIs for Hyperledger Fabric:
//
// By "membership service provider" we refer to an abstract component of the
Expand All @@ -34,25 +40,13 @@ package msp
// MSPManager is an interface defining a manager of one or more MSPs. This
// essentially acts as a mediator to MSP calls and routes MSP related calls
// to the appropriate MSP.
// This object is initialized (once) by calling Setup. Its
// internal configuration may be changed later by calling
// Reconfig. It is otherwise immutable.
// This object is immutable, it is initialized once and never changed.
type MSPManager interface {

// Setup the MSP manager instance according to configuration information
Setup(config *MSPManagerConfig) error

// Process reconfiguration messages (coming e.g., from Blockchain). This
// should take into consideration certain policies related to how, e.g.,
// a certain certificate should be considered valid, what constitutes the
// chain of trust, and who is authorized to change that.
// @param reconfigMessage The message containing the reconfiguration information.
Reconfig(config []byte) error
Setup(msps []*msp.MSPConfig) error

// Name of the MSP manager
GetName() string

// Provides a list of Membership Service providers
// GetMSPs Provides a list of Membership Service providers
GetMSPs() (map[string]MSP, error)

// DeserializeIdentity deserializes an identity
Expand All @@ -64,24 +58,15 @@ type MSPManager interface {
type MSP interface {

// Setup the MSP instance according to configuration information
Setup(config *MSPConfig) error

// Process reconfiguration messages coming from the blockchain
// @param reconfigMessage The message containing the reconfiguration command.
Reconfig(config []byte) error
Setup(config *msp.MSPConfig) error

// Get provider type
// GetType returns the provider type
GetType() ProviderType

// Get provider identifier
// GetIdentifier returns the provider identifier
GetIdentifier() (string, error)

// Obtain the policy to govern changes; this can be
// having a json format.
// Note: THIS CAN WAIT!
GetPolicy() string

// GetSingingIdentity returns a signing identity corresponding to the provided identifier
// GetSigningIdentity returns a signing identity corresponding to the provided identifier
GetSigningIdentity(identifier *IdentityIdentifier) (SigningIdentity, error)

// GetDefaultSigningIdentity returns the default signing identity
Expand All @@ -90,7 +75,7 @@ type MSP interface {
// DeserializeIdentity deserializes an identity
DeserializeIdentity(serializedIdentity []byte) (Identity, error)

// isValid checks whether the supplied identity is valid
// Validate checks whether the supplied identity is valid
Validate(id Identity) error
}

Expand All @@ -104,21 +89,20 @@ type MSP interface {
// with, and verifying signatures that correspond to these certificates.///
type Identity interface {

// Identifier returns the identifier of that identity
// GetIdentifier returns the identifier of that identity
GetIdentifier() *IdentityIdentifier

// Retrieve the provider identifier this identity belongs to
// from the previous field
// GetMSPIdentifier returns the MSP Id for this instance
GetMSPIdentifier() string

// This uses the rules that govern this identity to validate it.
// Validate uses the rules that govern this identity to validate it.
// E.g., if it is a fabric TCert implemented as identity, validate
// will check the TCert signature against the assumed root certificate
// authority.
IsValid() error
Validate() error

// TODO: Fix this comment
// ParticipantID would return the participant this identity is related to
// GetOrganizationUnits returns the participant this identity is related to
// as long as this is public information. In certain implementations
// this could be implemented by certain attributes that are publicly
// associated to that identity, or the identifier of the root certificate
Expand Down Expand Up @@ -162,7 +146,7 @@ type SigningIdentity interface {
// SignOpts the message with options
SignOpts(msg []byte, opts SignatureOpts) ([]byte, error)

// NewAttributeProof creates a proof for an attribute
// GetAttributeProof creates a proof for an attribute
GetAttributeProof(spec *AttributeProofSpec) (proof []byte, err error)

// GetPublicVersion returns the public parts of this identity
Expand Down

0 comments on commit 6444545

Please sign in to comment.