Skip to content
Snippets Groups Projects
Commit 8f781ceb authored by Jonathan Levi's avatar Jonathan Levi Committed by Gerrit Code Review
Browse files

Merge "[FAB-1778] Add chain config to configtx.Manager"

parents fff6ed66 676bf94f
Branches
Tags
No related merge requests found
......@@ -18,6 +18,7 @@ package configtx
import (
"github.com/hyperledger/fabric/common/cauthdsl"
"github.com/hyperledger/fabric/common/chainconfig"
"github.com/hyperledger/fabric/common/policies"
cb "github.com/hyperledger/fabric/protos/common"
)
......@@ -28,6 +29,9 @@ import (
type Resources interface {
// PolicyManager returns the policies.Manager for the chain
PolicyManager() policies.Manager
// ChainConfig returns the chainconfig.Descriptor for the chain
ChainConfig() chainconfig.Descriptor
}
// Initializer is a structure which is only useful before a configtx.Manager
......@@ -42,6 +46,7 @@ type Initializer interface {
type resources struct {
handlers map[cb.ConfigurationItem_ConfigurationType]Handler
policyManager policies.Manager
chainConfig chainconfig.Descriptor
}
// PolicyManager returns the policies.Manager for the chain
......@@ -49,6 +54,11 @@ func (r *resources) PolicyManager() policies.Manager {
return r.policyManager
}
// ChainConfig returns the chainconfig.Descriptor for the chain
func (r *resources) ChainConfig() chainconfig.Descriptor {
return r.chainConfig
}
// Handlers returns the handlers to be used when initializing the configtx.Manager
func (r *resources) Handlers() map[cb.ConfigurationItem_ConfigurationType]Handler {
return r.handlers
......@@ -71,11 +81,14 @@ func NewInitializer() Initializer {
}
policyManager := policies.NewManagerImpl(policyProviderMap)
chainConfig := chainconfig.NewDescriptorImpl()
handlers := make(map[cb.ConfigurationItem_ConfigurationType]Handler)
for ctype := range cb.ConfigurationItem_ConfigurationType_name {
rtype := cb.ConfigurationItem_ConfigurationType(ctype)
switch rtype {
case cb.ConfigurationItem_Chain:
handlers[rtype] = chainConfig
case cb.ConfigurationItem_Policy:
handlers[rtype] = policyManager
default:
......@@ -86,5 +99,6 @@ func NewInitializer() Initializer {
return &resources{
handlers: handlers,
policyManager: policyManager,
chainConfig: chainConfig,
}
}
......@@ -89,15 +89,17 @@ func (ct *compositeTemplate) Items(chainID string) ([]*cb.SignedConfigurationIte
type newChainTemplate struct {
creationPolicy string
hash func([]byte) []byte
template Template
}
// NewChainCreationTemplate takes a CreationPolicy and a Template to produce a Template which outputs an appropriately
// constructed list of SignedConfigurationItem including an appropriate digest. Note, using this Template in
// a CompositeTemplate will invalidate the CreationPolicy
func NewChainCreationTemplate(creationPolicy string, template Template) Template {
func NewChainCreationTemplate(creationPolicy string, hash func([]byte) []byte, template Template) Template {
return &newChainTemplate{
creationPolicy: creationPolicy,
hash: hash,
template: template,
}
}
......@@ -116,7 +118,7 @@ func (nct *newChainTemplate) Items(chainID string) ([]*cb.SignedConfigurationIte
Key: CreationPolicyKey,
Value: utils.MarshalOrPanic(&ab.CreationPolicy{
Policy: nct.creationPolicy,
Digest: HashItems(items),
Digest: HashItems(items, nct.hash),
}),
}),
}
......@@ -126,12 +128,12 @@ func (nct *newChainTemplate) Items(chainID string) ([]*cb.SignedConfigurationIte
// HashItems is a utility method for computing the hash of the concatenation of the marshaled ConfigurationItems
// in a []*cb.SignedConfigurationItem
func HashItems(items []*cb.SignedConfigurationItem) []byte {
func HashItems(items []*cb.SignedConfigurationItem, hash func([]byte) []byte) []byte {
sourceBytes := make([][]byte, len(items))
for i := range items {
sourceBytes[i] = items[i].ConfigurationItem
}
return util.ComputeCryptoHash(util.ConcatenateBytes(sourceBytes...))
return hash(util.ConcatenateBytes(sourceBytes...))
}
// join takes a number of SignedConfigurationItem slices and produces a single item
......@@ -154,7 +156,15 @@ func join(sets ...[]*cb.SignedConfigurationItem) []*cb.SignedConfigurationItem {
// MakeChainCreationTransaction is a handy utility function for creating new chain transactions using the underlying Template framework
func MakeChainCreationTransaction(creationPolicy string, chainID string, signer msp.SigningIdentity, templates ...Template) (*cb.Envelope, error) {
newChainTemplate := NewChainCreationTemplate(creationPolicy, NewCompositeTemplate(templates...))
composite := NewCompositeTemplate(templates...)
items, err := composite.Items(chainID)
if err != nil {
return nil, err
}
manager, err := NewManagerImpl(&cb.ConfigurationEnvelope{Items: items}, NewInitializer())
newChainTemplate := NewChainCreationTemplate(creationPolicy, manager.ChainConfig().HashingAlgorithm(), composite)
signedConfigItems, err := newChainTemplate.Items(chainID)
if err != nil {
return nil, err
......
......@@ -20,6 +20,7 @@ import (
"fmt"
"testing"
"github.com/hyperledger/fabric/common/util"
cb "github.com/hyperledger/fabric/protos/common"
"github.com/hyperledger/fabric/protos/utils"
"github.com/stretchr/testify/assert"
......@@ -79,7 +80,7 @@ func TestNewChainTemplate(t *testing.T) {
)
creationPolicy := "Test"
nct := NewChainCreationTemplate(creationPolicy, simple)
nct := NewChainCreationTemplate(creationPolicy, util.ComputeCryptoHash, simple)
newChainID := "foo"
items, err := nct.Items(newChainID)
......
No preview for this file type
......@@ -19,12 +19,12 @@ package chainconfig
import "github.com/hyperledger/fabric/common/util"
func nearIdentityHash(input []byte) []byte {
return util.ConcatenateBytes([]byte("Hash("), input, []byte(""))
return util.ConcatenateBytes([]byte("FakeHash("), input, []byte(""))
}
// Descriptor is a mock implementation of sharedconfig.Descriptor
type Descriptor struct {
// HashingAlgorithmVal is returned as the result of HashingAlgorithm()
// HashingAlgorithmVal is returned as the result of HashingAlgorithm() if set
HashingAlgorithmVal func([]byte) []byte
// BlockDataHashingStructureWidthVal is returned as the result of BlockDataHashingStructureWidth()
BlockDataHashingStructureWidthVal uint32
......@@ -32,8 +32,11 @@ type Descriptor struct {
OrdererAddressesVal []string
}
// HashingAlgorithm returns the HashingAlgorithmVal
// HashingAlgorithm returns the HashingAlgorithmVal if set, otherwise a fake simple hash function
func (scm *Descriptor) HashingAlgorithm() func([]byte) []byte {
if scm.HashingAlgorithmVal == nil {
return nearIdentityHash
}
return scm.HashingAlgorithmVal
}
......
......@@ -19,6 +19,7 @@ package validation
import (
"testing"
"github.com/hyperledger/fabric/common/chainconfig"
"github.com/hyperledger/fabric/common/configtx"
"github.com/hyperledger/fabric/common/configtx/test"
"github.com/hyperledger/fabric/common/util"
......@@ -29,7 +30,8 @@ func TestValidateConfigTx(t *testing.T) {
chainID := util.GetTestChainID()
oTemplate := test.GetOrdererTemplate()
mspcfg := configtx.NewSimpleTemplate(utils.EncodeMSPUnsigned(chainID))
chCrtTemp := configtx.NewCompositeTemplate(oTemplate, mspcfg)
chainCfg := configtx.NewSimpleTemplate(chainconfig.DefaultHashingAlgorithm())
chCrtTemp := configtx.NewCompositeTemplate(oTemplate, mspcfg, chainCfg)
chCrtEnv, err := configtx.MakeChainCreationTransaction(test.AcceptAllPolicyKey, chainID, signer, chCrtTemp)
if err != nil {
t.Fatalf("MakeChainCreationTransaction failed, err %s", err)
......
......@@ -20,6 +20,7 @@ import (
"fmt"
"github.com/hyperledger/fabric/common/cauthdsl"
"github.com/hyperledger/fabric/common/chainconfig"
"github.com/hyperledger/fabric/common/configtx"
"github.com/hyperledger/fabric/common/genesis"
"github.com/hyperledger/fabric/orderer/common/bootstrap"
......@@ -67,6 +68,11 @@ type bootstrapper struct {
func New(conf *config.TopLevel) Generator {
bs := &bootstrapper{
minimalItems: []*cb.ConfigurationItem{
// Chain Config Types
chainconfig.DefaultHashingAlgorithm(),
chainconfig.DefaultBlockDataHashingStructure(),
chainconfig.TemplateOrdererAddresses([]string{fmt.Sprintf("%s:%d", conf.General.ListenAddress, conf.General.ListenPort)}),
// Orderer Config Types
sharedconfig.TemplateConsensusType(conf.Genesis.OrdererType),
sharedconfig.TemplateBatchSize(&ab.BatchSize{
......
......@@ -17,6 +17,7 @@ limitations under the License.
package configtx
import (
"github.com/hyperledger/fabric/common/chainconfig"
"github.com/hyperledger/fabric/common/configtx"
"github.com/hyperledger/fabric/common/policies"
cb "github.com/hyperledger/fabric/protos/common"
......@@ -28,6 +29,9 @@ type Initializer struct {
// PolicyManagerVal is returned as the result of PolicyManager()
PolicyManagerVal policies.Manager
// ChainConfigVal is returned as the result of ChainConfig()
ChainConfigVal chainconfig.Descriptor
}
// Returns the HandlersVal
......@@ -40,6 +44,11 @@ func (i *Initializer) PolicyManager() policies.Manager {
return i.PolicyManagerVal
}
// Returns the ChainConfigVal
func (i *Initializer) ChainConfig() chainconfig.Descriptor {
return i.ChainConfigVal
}
// Manager is a mock implementation of configtx.Manager
type Manager struct {
Initializer
......
......@@ -19,6 +19,7 @@ package multichain
import (
"bytes"
"github.com/hyperledger/fabric/common/chainconfig"
"github.com/hyperledger/fabric/common/configtx"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/orderer/common/filter"
......@@ -39,6 +40,7 @@ type limitedSupport interface {
ChainID() string
PolicyManager() policies.Manager
SharedConfig() sharedconfig.Manager
ChainConfig() chainconfig.Descriptor
Enqueue(env *cb.Envelope) bool
}
......@@ -193,7 +195,7 @@ func (sc *systemChain) authorize(configEnvelope *cb.ConfigurationEnvelope) cb.St
// XXX actually do policy signature validation
_ = policy
configHash := configtx.HashItems(configEnvelope.Items[1:])
configHash := configtx.HashItems(configEnvelope.Items[1:], sc.support.ChainConfig().HashingAlgorithm())
if !bytes.Equal(configHash, creationPolicy.Digest) {
logger.Debugf("Validly signed chain creation did not contain correct digest for remaining configuration %x vs. %x", configHash, creationPolicy.Digest)
......
......@@ -20,7 +20,9 @@ import (
"reflect"
"testing"
"github.com/hyperledger/fabric/common/chainconfig"
"github.com/hyperledger/fabric/common/configtx"
mockchainconfig "github.com/hyperledger/fabric/common/mocks/chainconfig"
"github.com/hyperledger/fabric/common/policies"
coreutil "github.com/hyperledger/fabric/common/util"
"github.com/hyperledger/fabric/orderer/common/bootstrap/provisional"
......@@ -53,6 +55,7 @@ type mockSupport struct {
msc *mocksharedconfig.Manager
chainID string
queue []*cb.Envelope
chainConfig *mockchainconfig.Descriptor
}
func newMockSupport(chainID string) *mockSupport {
......@@ -60,6 +63,7 @@ func newMockSupport(chainID string) *mockSupport {
mpm: &mockPolicyManager{},
msc: &mocksharedconfig.Manager{},
chainID: chainID,
chainConfig: &mockchainconfig.Descriptor{},
}
}
......@@ -80,6 +84,10 @@ func (ms *mockSupport) SharedConfig() sharedconfig.Manager {
return ms.msc
}
func (ms *mockSupport) ChainConfig() chainconfig.Descriptor {
return ms.chainConfig
}
type mockChainCreator struct {
newChains []*cb.Envelope
ms *mockSupport
......@@ -118,7 +126,7 @@ func TestGoodProposal(t *testing.T) {
Type: cb.ConfigurationItem_Orderer,
Value: utils.MarshalOrPanic(&ab.CreationPolicy{
Policy: provisional.AcceptAllPolicyKey,
Digest: coreutil.ComputeCryptoHash([]byte{}),
Digest: mcc.ms.ChainConfig().HashingAlgorithm()([]byte{}),
}),
}
ingressTx := makeConfigTxWithItems(newChainID, chainCreateTx)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment