Skip to content

Commit

Permalink
[FAB-6223] Define resource tree config protos
Browse files Browse the repository at this point in the history
The resource tree needs to represent both API ACLs as well as
chaincodes.

This CR renames the Resource message to APIResource and adds a
collection of Chaincode messages for defining the chaincode group.

For the new Chaincode group, there is now a structure of:

[Group] Resources
    [Group] Chaincodes
        [Group] mycc
            [Value] ChaincodeIdentifier
                bytes hash = 1;
                string version = 2;
            [Value] ChaincodeValidation
                string name = 1;     // Set to vscc
                bytes argument  = 2; // A marshaled:
                    message VSCCArgs
                        string endorsement_policy_ref = 1;
            [Value] ChaincodeEndorsement
                string name = 1; // Set to escc

Change-Id: Ic2d02fb11a55779031eedce898902bc67185a4aa
Signed-off-by: Jason Yellick <[email protected]>
  • Loading branch information
Jason Yellick committed Nov 2, 2017
1 parent cc29eed commit c3bfd6d
Show file tree
Hide file tree
Showing 8 changed files with 338 additions and 34 deletions.
2 changes: 1 addition & 1 deletion common/resourcesconfig/apis.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func newAPIsGroup(group *cb.ConfigGroup) (*apisGroup, error) {
apiPolicyRefs := make(map[string]string)

for key, value := range group.Values {
api := &pb.Resource{}
api := &pb.APIResource{}
if err := proto.Unmarshal(value.Value, api); err != nil {
return nil, err
}
Expand Down
8 changes: 4 additions & 4 deletions common/resourcesconfig/bundle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ func TestBundleGreenPath(t *testing.T) {
APIsGroupKey: &cb.ConfigGroup{
Values: map[string]*cb.ConfigValue{
"Foo": &cb.ConfigValue{
Value: utils.MarshalOrPanic(&pb.Resource{
Value: utils.MarshalOrPanic(&pb.APIResource{
PolicyRef: "foo",
}),
},
"Bar": &cb.ConfigValue{
Value: utils.MarshalOrPanic(&pb.Resource{
Value: utils.MarshalOrPanic(&pb.APIResource{
PolicyRef: "/Channel/foo",
}),
},
Expand Down Expand Up @@ -87,8 +87,8 @@ func TestBundleBadSubGroup(t *testing.T) {
Groups: map[string]*cb.ConfigGroup{
PeerPoliciesGroupKey: &cb.ConfigGroup{
Values: map[string]*cb.ConfigValue{
"Foo": {
Value: utils.MarshalOrPanic(&pb.Resource{
"Foo": &cb.ConfigValue{
Value: utils.MarshalOrPanic(&pb.APIResource{
PolicyRef: "foo",
}),
},
Expand Down
52 changes: 52 additions & 0 deletions common/tools/protolator/blackbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
genesisconfig "github.com/hyperledger/fabric/common/tools/configtxgen/localconfig"
. "github.com/hyperledger/fabric/common/tools/protolator"
cb "github.com/hyperledger/fabric/protos/common"
pb "github.com/hyperledger/fabric/protos/peer"
"github.com/hyperledger/fabric/protos/utils"

"github.com/golang/protobuf/proto"
Expand Down Expand Up @@ -72,3 +73,54 @@ func TestGenesisBlock(t *testing.T) {

bidirectionalMarshal(t, gb)
}

func TestResourcesConfig(t *testing.T) {
p := &cb.Config{
Type: int32(cb.ConfigType_RESOURCE),
ChannelGroup: &cb.ConfigGroup{
Groups: map[string]*cb.ConfigGroup{
"Chaincodes": &cb.ConfigGroup{
Groups: map[string]*cb.ConfigGroup{
"cc1": &cb.ConfigGroup{
Values: map[string]*cb.ConfigValue{
"ChaincodeIdentifier": &cb.ConfigValue{
Value: utils.MarshalOrPanic(&pb.ChaincodeIdentifier{
Hash: []byte("somehashvalue"),
Version: "aversionstring",
}),
},
"ChaincodeValidation": &cb.ConfigValue{
Value: utils.MarshalOrPanic(
&pb.ChaincodeValidation{
Name: "vscc",
Argument: utils.MarshalOrPanic(&pb.VSCCArgs{
EndorsementPolicyRef: "foo",
}),
}),
},
"ChaincodeEndorsement": &cb.ConfigValue{
Value: utils.MarshalOrPanic(&pb.ChaincodeEndorsement{
Name: "escc",
}),
},
},
},
},
},
"APIs": &cb.ConfigGroup{
Values: map[string]*cb.ConfigValue{
"Test": &cb.ConfigValue{
Value: utils.MarshalOrPanic(&pb.APIResource{PolicyRef: "Foo"}),
},
"Another": &cb.ConfigValue{
Value: utils.MarshalOrPanic(&pb.APIResource{PolicyRef: "Bar"}),
},
},
},
"PeerPolicies": &cb.ConfigGroup{},
},
},
}

bidirectionalMarshal(t, p)
}
2 changes: 1 addition & 1 deletion core/scc/rscc/rscc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func createConfig() []byte {
// All of the default seed data values would inside this ConfigGroup
Values: map[string]*common.ConfigValue{
"res": &common.ConfigValue{
Value: utils.MarshalOrPanic(&pb.Resource{
Value: utils.MarshalOrPanic(&pb.APIResource{
PolicyRef: "respol",
}),
ModPolicy: "resmodpol",
Expand Down
6 changes: 5 additions & 1 deletion protos/peer/admin.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

117 changes: 112 additions & 5 deletions protos/peer/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,32 +33,139 @@ type DynamicResourceConfigGroup struct {
}

func (drcg *DynamicResourceConfigGroup) DynamicMapFields() []string {
return []string{"values"}
return []string{"values", "groups"}
}

func (drcg *DynamicResourceConfigGroup) DynamicMapFieldProto(name string, key string, base proto.Message) (proto.Message, error) {
switch name {
case "groups":
cg, ok := base.(*common.ConfigGroup)
if !ok {
return nil, fmt.Errorf("ConfigGroup groups can only contain ConfigGroup messages")
}
switch key {
case "APIs":
return &DynamicResourceAPIsConfigGroup{ConfigGroup: cg}, nil
case "Chaincodes":
return &DynamicResourceChaincodesConfigGroup{ConfigGroup: cg}, nil
case "PeerPolicies":
return cg, nil
}
}
return nil, fmt.Errorf("ConfigGroup does not have a dynamic field: %s", name)
}

type DynamicResourceChaincodesConfigGroup struct {
*common.ConfigGroup
}

func (draccg *DynamicResourceChaincodesConfigGroup) DynamicMapFields() []string {
return []string{"groups"}
}

func (drccg *DynamicResourceChaincodesConfigGroup) DynamicMapFieldProto(name string, key string, base proto.Message) (proto.Message, error) {
switch name {
case "groups":
cg, ok := base.(*common.ConfigGroup)
if !ok {
return nil, fmt.Errorf("ConfigGroup groups can only contain ConfigGroup messages")
}
return &DynamicResourceChaincodeConfigGroup{ConfigGroup: cg}, nil
default:
return nil, fmt.Errorf("ConfigGroup does not have a dynamic field: %s", name)
}
}

type DynamicResourceChaincodeConfigGroup struct {
*common.ConfigGroup
}

func (draccg *DynamicResourceChaincodeConfigGroup) DynamicMapFields() []string {
return []string{"values"}
}

func (drccg *DynamicResourceChaincodeConfigGroup) DynamicMapFieldProto(name string, key string, base proto.Message) (proto.Message, error) {
switch name {
case "values":
cv, ok := base.(*common.ConfigValue)
if !ok {
return nil, fmt.Errorf("ConfigGroup groups can only contain ConfigValue messages")
}
return &DynamicResourceChaincodeConfigValue{ConfigValue: cv, key: key}, nil
default:
return nil, fmt.Errorf("ConfigGroup does not have a dynamic field: %s", name)
}
}

type DynamicResourceChaincodeConfigValue struct {
*common.ConfigValue
key string
}

func (drccv *DynamicResourceChaincodeConfigValue) VariablyOpaqueFieldProto(name string) (proto.Message, error) {
if name != drccv.VariablyOpaqueFields()[0] {
return nil, fmt.Errorf("Not a marshaled field: %s", name)
}

switch drccv.key {
case "ChaincodeIdentifier":
return &ChaincodeIdentifier{}, nil
case "ChaincodeValidation":
return &ChaincodeValidation{}, nil
case "ChaincodeEndorsement":
return &ChaincodeEndorsement{}, nil
default:
return nil, fmt.Errorf("unknown value key: %s", drccv.key)
}
}

func (cv *ChaincodeValidation) VariablyOpaqueFields() []string {
return []string{"argument"}
}

func (cv *ChaincodeValidation) VariablyOpaqueFieldProto(name string) (proto.Message, error) {
if name != cv.VariablyOpaqueFields()[0] {
return nil, fmt.Errorf("not a marshaled field: %s", name)
}
switch cv.Name {
case "vscc":
return &VSCCArgs{}, nil
default:
return nil, fmt.Errorf("unknown validation name: %s", cv.Name)
}
}

type DynamicResourceAPIsConfigGroup struct {
*common.ConfigGroup
}

func (dracg *DynamicResourceAPIsConfigGroup) DynamicMapFields() []string {
return []string{"values"}
}

func (dracg *DynamicResourceAPIsConfigGroup) DynamicMapFieldProto(name string, key string, base proto.Message) (proto.Message, error) {
switch name {
case "values":
cv, ok := base.(*common.ConfigValue)
if !ok {
return nil, fmt.Errorf("ConfigGroup values can only contain ConfigValue messages")
}
return &DynamicResourceConfigValue{
return &DynamicResourceAPIsConfigValue{
ConfigValue: cv,
}, nil
default:
return nil, fmt.Errorf("ConfigGroup does not have a dynamic field: %s", name)
}
}

type DynamicResourceConfigValue struct {
type DynamicResourceAPIsConfigValue struct {
*common.ConfigValue
}

func (drcv *DynamicResourceConfigValue) VariablyOpaqueFieldProto(name string) (proto.Message, error) {
func (drcv *DynamicResourceAPIsConfigValue) VariablyOpaqueFieldProto(name string) (proto.Message, error) {
if name != drcv.VariablyOpaqueFields()[0] {
return nil, fmt.Errorf("Not a marshaled field: %s", name)
}

return &Resource{}, nil
return &APIResource{}, nil
}
Loading

0 comments on commit c3bfd6d

Please sign in to comment.