Documentation ¶
Index ¶
- type CommonStorageDB
- func (s *CommonStorageDB) ApplyPrivacyAwareUpdates(updates *UpdateBatch, height *version.Height) error
- func (s *CommonStorageDB) ApplyUpdates(batch *statedb.UpdateBatch, height *version.Height) error
- func (s *CommonStorageDB) ChaincodeDeployDone(succeeded bool)
- func (s *CommonStorageDB) ClearCachedVersions()
- func (s CommonStorageDB) ExecuteQueryOnPrivateData(namespace, collection, query string) (statedb.ResultsIterator, error)
- func (s *CommonStorageDB) GetCachedKeyHashVersion(namespace, collection string, keyHash []byte) (*version.Height, bool)
- func (s *CommonStorageDB) GetChaincodeEventListener() cceventmgmt.ChaincodeLifecycleEventListener
- func (s *CommonStorageDB) GetKeyHashVersion(namespace, collection string, keyHash []byte) (*version.Height, error)
- func (s *CommonStorageDB) GetPrivateData(namespace, collection, key string) (*statedb.VersionedValue, error)
- func (s *CommonStorageDB) GetPrivateDataMetadataByHash(namespace, collection string, keyHash []byte) ([]byte, error)
- func (s *CommonStorageDB) GetPrivateDataMultipleKeys(namespace, collection string, keys []string) ([]*statedb.VersionedValue, error)
- func (s *CommonStorageDB) GetPrivateDataRangeScanIterator(namespace, collection, startKey, endKey string) (statedb.ResultsIterator, error)
- func (s *CommonStorageDB) GetStateMetadata(namespace, key string) ([]byte, error)
- func (s *CommonStorageDB) GetValueHash(namespace, collection string, keyHash []byte) (*statedb.VersionedValue, error)
- func (s *CommonStorageDB) HandleChaincodeDeploy(chaincodeDefinition *cceventmgmt.ChaincodeDefinition, dbArtifactsTar []byte) error
- func (s *CommonStorageDB) IsBulkOptimizable() bool
- func (s *CommonStorageDB) LoadCommittedVersionsOfPubAndHashedKeys(pubKeys []*statedb.CompositeKey, hashedKeys []*HashedCompositeKey) error
- type CommonStorageDBProvider
- type CouchDBCommonStorageTestEnv
- type DB
- type DBProvider
- type HashedCompositeKey
- type HashedUpdateBatch
- func (h HashedUpdateBatch) Contains(ns, coll string, keyHash []byte) bool
- func (h HashedUpdateBatch) Delete(ns, coll string, key []byte, version *version.Height)
- func (h HashedUpdateBatch) Put(ns, coll string, key []byte, value []byte, version *version.Height)
- func (h HashedUpdateBatch) PutValHashAndMetadata(ns, coll string, key []byte, value []byte, metadata []byte, ...)
- func (h HashedUpdateBatch) ToCompositeKeyMap() map[HashedCompositeKey]*statedb.VersionedValue
- type KVWriteProto
- func (*KVWriteProto) Descriptor() ([]byte, []int)
- func (m *KVWriteProto) GetCollection() string
- func (m *KVWriteProto) GetIsDelete() bool
- func (m *KVWriteProto) GetKey() []byte
- func (m *KVWriteProto) GetNamespace() string
- func (m *KVWriteProto) GetValue() []byte
- func (m *KVWriteProto) GetVersionBytes() []byte
- func (*KVWriteProto) ProtoMessage()
- func (m *KVWriteProto) Reset()
- func (m *KVWriteProto) String() string
- func (m *KVWriteProto) XXX_DiscardUnknown()
- func (m *KVWriteProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
- func (dst *KVWriteProto) XXX_Merge(src proto.Message)
- func (m *KVWriteProto) XXX_Size() int
- func (m *KVWriteProto) XXX_Unmarshal(b []byte) error
- type KVWritesBatchProto
- func (*KVWritesBatchProto) Descriptor() ([]byte, []int)
- func (m *KVWritesBatchProto) GetKvwrites() []*KVWriteProto
- func (*KVWritesBatchProto) ProtoMessage()
- func (m *KVWritesBatchProto) Reset()
- func (m *KVWritesBatchProto) String() string
- func (m *KVWritesBatchProto) XXX_DiscardUnknown()
- func (m *KVWritesBatchProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
- func (dst *KVWritesBatchProto) XXX_Merge(src proto.Message)
- func (m *KVWritesBatchProto) XXX_Size() int
- func (m *KVWritesBatchProto) XXX_Unmarshal(b []byte) error
- type LevelDBCommonStorageTestEnv
- type PubUpdateBatch
- type PvtKVWrite
- type PvtUpdateBatch
- type PvtdataCompositeKey
- type PvtdataCompositeKeyMap
- type TestEnv
- type UpdateBatch
- type UpdateMap
- func (b UpdateMap) Contains(ns, coll, key string) bool
- func (b UpdateMap) Delete(ns, coll, key string, version *version.Height)
- func (b UpdateMap) Get(ns, coll, key string) *statedb.VersionedValue
- func (b UpdateMap) IsEmpty() bool
- func (b UpdateMap) Put(ns, coll, key string, value []byte, version *version.Height)
- func (b UpdateMap) PutValAndMetadata(ns, coll, key string, value []byte, metadata []byte, version *version.Height)
- type UpdatesBytesBuilder
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CommonStorageDB ¶
type CommonStorageDB struct { statedb.VersionedDB // contains filtered or unexported fields }
CommonStorageDB implements interface DB. This implementation uses a single database to maintain both the public and private data
func (*CommonStorageDB) ApplyPrivacyAwareUpdates ¶
func (s *CommonStorageDB) ApplyPrivacyAwareUpdates(updates *UpdateBatch, height *version.Height) error
ApplyPrivacyAwareUpdates implements corresponding function in interface DB
func (*CommonStorageDB) ApplyUpdates ¶
func (s *CommonStorageDB) ApplyUpdates(batch *statedb.UpdateBatch, height *version.Height) error
ApplyUpdates overrides the function in statedb.VersionedDB and throws appropriate error message Otherwise, somewhere in the code, usage of this function could lead to updating only public data.
func (*CommonStorageDB) ChaincodeDeployDone ¶
func (s *CommonStorageDB) ChaincodeDeployDone(succeeded bool)
ChaincodeDeployDone is a noop for couchdb state impl
func (*CommonStorageDB) ClearCachedVersions ¶
func (s *CommonStorageDB) ClearCachedVersions()
ClearCachedVersions implements corresponding function in interface DB
func (CommonStorageDB) ExecuteQueryOnPrivateData ¶
func (s CommonStorageDB) ExecuteQueryOnPrivateData(namespace, collection, query string) (statedb.ResultsIterator, error)
ExecuteQueryOnPrivateData implements corresponding function in interface DB
func (*CommonStorageDB) GetCachedKeyHashVersion ¶
func (s *CommonStorageDB) GetCachedKeyHashVersion(namespace, collection string, keyHash []byte) (*version.Height, bool)
GetCachedKeyHashVersion retrieves the keyhash version from cache
func (*CommonStorageDB) GetChaincodeEventListener ¶
func (s *CommonStorageDB) GetChaincodeEventListener() cceventmgmt.ChaincodeLifecycleEventListener
GetChaincodeEventListener implements corresponding function in interface DB
func (*CommonStorageDB) GetKeyHashVersion ¶
func (s *CommonStorageDB) GetKeyHashVersion(namespace, collection string, keyHash []byte) (*version.Height, error)
GetKeyHashVersion implements corresponding function in interface DB
func (*CommonStorageDB) GetPrivateData ¶
func (s *CommonStorageDB) GetPrivateData(namespace, collection, key string) (*statedb.VersionedValue, error)
GetPrivateData implements corresponding function in interface DB
func (*CommonStorageDB) GetPrivateDataMetadataByHash ¶
func (s *CommonStorageDB) GetPrivateDataMetadataByHash(namespace, collection string, keyHash []byte) ([]byte, error)
GetPrivateDataMetadataByHash implements corresponding function in interface DB. For additional details, see description of the similar function 'GetStateMetadata'
func (*CommonStorageDB) GetPrivateDataMultipleKeys ¶
func (s *CommonStorageDB) GetPrivateDataMultipleKeys(namespace, collection string, keys []string) ([]*statedb.VersionedValue, error)
GetPrivateDataMultipleKeys implements corresponding function in interface DB
func (*CommonStorageDB) GetPrivateDataRangeScanIterator ¶
func (s *CommonStorageDB) GetPrivateDataRangeScanIterator(namespace, collection, startKey, endKey string) (statedb.ResultsIterator, error)
GetPrivateDataRangeScanIterator implements corresponding function in interface DB
func (*CommonStorageDB) GetStateMetadata ¶
func (s *CommonStorageDB) GetStateMetadata(namespace, key string) ([]byte, error)
GetStateMetadata implements corresponding function in interface DB. This implementation provides an optimization such that it keeps track if a namespaces has never stored metadata for any of its items, the value 'nil' is returned without going to the db. This is intended to be invoked in the validation and commit path. This saves the chaincodes from paying unnecessary performance penalty if they do not use features that leverage metadata (such as key-level endorsement),
func (*CommonStorageDB) GetValueHash ¶
func (s *CommonStorageDB) GetValueHash(namespace, collection string, keyHash []byte) (*statedb.VersionedValue, error)
GetValueHash implements corresponding function in interface DB
func (*CommonStorageDB) HandleChaincodeDeploy ¶
func (s *CommonStorageDB) HandleChaincodeDeploy(chaincodeDefinition *cceventmgmt.ChaincodeDefinition, dbArtifactsTar []byte) error
HandleChaincodeDeploy initializes database artifacts for the database associated with the namespace This function deliberately suppresses the errors that occur during the creation of the indexes on couchdb. This is because, in the present code, we do not differentiate between the errors because of couchdb interaction and the errors because of bad index files - the later being unfixable by the admin. Note that the error suppression is acceptable since peer can continue in the committing role without the indexes. However, executing chaincode queries may be affected, until a new chaincode with fixed indexes is installed and instantiated
func (*CommonStorageDB) IsBulkOptimizable ¶
func (s *CommonStorageDB) IsBulkOptimizable() bool
IsBulkOptimizable implements corresponding function in interface DB
func (*CommonStorageDB) LoadCommittedVersionsOfPubAndHashedKeys ¶
func (s *CommonStorageDB) LoadCommittedVersionsOfPubAndHashedKeys(pubKeys []*statedb.CompositeKey, hashedKeys []*HashedCompositeKey) error
LoadCommittedVersionsOfPubAndHashedKeys implements corresponding function in interface DB
type CommonStorageDBProvider ¶
type CommonStorageDBProvider struct { statedb.VersionedDBProvider HealthCheckRegistry ledger.HealthCheckRegistry // contains filtered or unexported fields }
CommonStorageDBProvider implements interface DBProvider
func (*CommonStorageDBProvider) Close ¶
func (p *CommonStorageDBProvider) Close()
Close implements function from interface DBProvider
func (*CommonStorageDBProvider) GetDBHandle ¶
func (p *CommonStorageDBProvider) GetDBHandle(id string) (DB, error)
GetDBHandle implements function from interface DBProvider
func (*CommonStorageDBProvider) RegisterHealthChecker ¶
func (p *CommonStorageDBProvider) RegisterHealthChecker() error
type CouchDBCommonStorageTestEnv ¶
type CouchDBCommonStorageTestEnv struct {
// contains filtered or unexported fields
}
CouchDBCommonStorageTestEnv implements TestEnv interface for couchdb based storage
func (*CouchDBCommonStorageTestEnv) Cleanup ¶
func (env *CouchDBCommonStorageTestEnv) Cleanup()
Cleanup implements corresponding function from interface TestEnv
func (*CouchDBCommonStorageTestEnv) GetDBHandle ¶
func (env *CouchDBCommonStorageTestEnv) GetDBHandle(id string) DB
GetDBHandle implements corresponding function from interface TestEnv
func (*CouchDBCommonStorageTestEnv) GetName ¶
func (env *CouchDBCommonStorageTestEnv) GetName() string
GetName implements corresponding function from interface TestEnv
func (*CouchDBCommonStorageTestEnv) Init ¶
func (env *CouchDBCommonStorageTestEnv) Init(t testing.TB)
Init implements corresponding function from interface TestEnv
type DB ¶
type DB interface { statedb.VersionedDB IsBulkOptimizable() bool LoadCommittedVersionsOfPubAndHashedKeys(pubKeys []*statedb.CompositeKey, hashedKeys []*HashedCompositeKey) error GetCachedKeyHashVersion(namespace, collection string, keyHash []byte) (*version.Height, bool) ClearCachedVersions() GetChaincodeEventListener() cceventmgmt.ChaincodeLifecycleEventListener GetPrivateData(namespace, collection, key string) (*statedb.VersionedValue, error) GetValueHash(namespace, collection string, keyHash []byte) (*statedb.VersionedValue, error) GetKeyHashVersion(namespace, collection string, keyHash []byte) (*version.Height, error) GetPrivateDataMultipleKeys(namespace, collection string, keys []string) ([]*statedb.VersionedValue, error) GetPrivateDataRangeScanIterator(namespace, collection, startKey, endKey string) (statedb.ResultsIterator, error) GetStateMetadata(namespace, key string) ([]byte, error) GetPrivateDataMetadataByHash(namespace, collection string, keyHash []byte) ([]byte, error) ExecuteQueryOnPrivateData(namespace, collection, query string) (statedb.ResultsIterator, error) ApplyPrivacyAwareUpdates(updates *UpdateBatch, height *version.Height) error }
DB extends VersionedDB interface. This interface provides additional functions for managing private data state
func NewCommonStorageDB ¶
func NewCommonStorageDB(vdb statedb.VersionedDB, ledgerid string, metadataHint *metadataHint) (DB, error)
NewCommonStorageDB wraps a VersionedDB instance. The public data is managed directly by the wrapped versionedDB. For managing the hashed data and private data, this implementation creates separate namespaces in the wrapped db
type DBProvider ¶
type DBProvider interface { // GetDBHandle returns a handle to a PvtVersionedDB GetDBHandle(id string) (DB, error) // Close closes all the PvtVersionedDB instances and releases any resources held by VersionedDBProvider Close() }
DBProvider provides handle to a PvtVersionedDB
func NewCommonStorageDBProvider ¶
func NewCommonStorageDBProvider(bookkeeperProvider bookkeeping.Provider, metricsProvider metrics.Provider, healthCheckRegistry ledger.HealthCheckRegistry) (DBProvider, error)
NewCommonStorageDBProvider constructs an instance of DBProvider
type HashedCompositeKey ¶
HashedCompositeKey encloses Namespace, CollectionName and KeyHash components
func (*HashedCompositeKey) String ¶
func (hck *HashedCompositeKey) String() string
String returns a print friendly form of HashedCompositeKey
type HashedUpdateBatch ¶
type HashedUpdateBatch struct {
UpdateMap
}
HashedUpdateBatch contains updates for the hashes of the private data
func NewHashedUpdateBatch ¶
func NewHashedUpdateBatch() *HashedUpdateBatch
NewHashedUpdateBatch creates an empty HashedUpdateBatch
func (HashedUpdateBatch) Contains ¶
func (h HashedUpdateBatch) Contains(ns, coll string, keyHash []byte) bool
Contains returns true if the given <ns,coll,keyHash> tuple is present in the batch
func (HashedUpdateBatch) Delete ¶
func (h HashedUpdateBatch) Delete(ns, coll string, key []byte, version *version.Height)
Delete overrides the function in UpdateMap for allowing the key to be a []byte instead of a string
func (HashedUpdateBatch) Put ¶
Put overrides the function in UpdateMap for allowing the key to be a []byte instead of a string
func (HashedUpdateBatch) PutValHashAndMetadata ¶
func (h HashedUpdateBatch) PutValHashAndMetadata(ns, coll string, key []byte, value []byte, metadata []byte, version *version.Height)
PutValHashAndMetadata adds a key with value and metadata TODO introducing a new function to limit the refactoring. Later in a separate CR, the 'Put' function above should be removed
func (HashedUpdateBatch) ToCompositeKeyMap ¶
func (h HashedUpdateBatch) ToCompositeKeyMap() map[HashedCompositeKey]*statedb.VersionedValue
ToCompositeKeyMap rearranges the update batch data in the form of a single map
type KVWriteProto ¶
type KVWriteProto struct { Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` Collection string `protobuf:"bytes,2,opt,name=collection,proto3" json:"collection,omitempty"` Key []byte `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` IsDelete bool `protobuf:"varint,4,opt,name=isDelete,proto3" json:"isDelete,omitempty"` Value []byte `protobuf:"bytes,5,opt,name=value,proto3" json:"value,omitempty"` VersionBytes []byte `protobuf:"bytes,6,opt,name=version_bytes,json=versionBytes,proto3" json:"version_bytes,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` }
func (*KVWriteProto) Descriptor ¶
func (*KVWriteProto) Descriptor() ([]byte, []int)
func (*KVWriteProto) GetCollection ¶
func (m *KVWriteProto) GetCollection() string
func (*KVWriteProto) GetIsDelete ¶
func (m *KVWriteProto) GetIsDelete() bool
func (*KVWriteProto) GetKey ¶
func (m *KVWriteProto) GetKey() []byte
func (*KVWriteProto) GetNamespace ¶
func (m *KVWriteProto) GetNamespace() string
func (*KVWriteProto) GetValue ¶
func (m *KVWriteProto) GetValue() []byte
func (*KVWriteProto) GetVersionBytes ¶
func (m *KVWriteProto) GetVersionBytes() []byte
func (*KVWriteProto) ProtoMessage ¶
func (*KVWriteProto) ProtoMessage()
func (*KVWriteProto) Reset ¶
func (m *KVWriteProto) Reset()
func (*KVWriteProto) String ¶
func (m *KVWriteProto) String() string
func (*KVWriteProto) XXX_DiscardUnknown ¶
func (m *KVWriteProto) XXX_DiscardUnknown()
func (*KVWriteProto) XXX_Marshal ¶
func (m *KVWriteProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
func (*KVWriteProto) XXX_Merge ¶
func (dst *KVWriteProto) XXX_Merge(src proto.Message)
func (*KVWriteProto) XXX_Size ¶
func (m *KVWriteProto) XXX_Size() int
func (*KVWriteProto) XXX_Unmarshal ¶
func (m *KVWriteProto) XXX_Unmarshal(b []byte) error
type KVWritesBatchProto ¶
type KVWritesBatchProto struct { Kvwrites []*KVWriteProto `protobuf:"bytes,1,rep,name=kvwrites,proto3" json:"kvwrites,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` }
func (*KVWritesBatchProto) Descriptor ¶
func (*KVWritesBatchProto) Descriptor() ([]byte, []int)
func (*KVWritesBatchProto) GetKvwrites ¶
func (m *KVWritesBatchProto) GetKvwrites() []*KVWriteProto
func (*KVWritesBatchProto) ProtoMessage ¶
func (*KVWritesBatchProto) ProtoMessage()
func (*KVWritesBatchProto) Reset ¶
func (m *KVWritesBatchProto) Reset()
func (*KVWritesBatchProto) String ¶
func (m *KVWritesBatchProto) String() string
func (*KVWritesBatchProto) XXX_DiscardUnknown ¶
func (m *KVWritesBatchProto) XXX_DiscardUnknown()
func (*KVWritesBatchProto) XXX_Marshal ¶
func (m *KVWritesBatchProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
func (*KVWritesBatchProto) XXX_Merge ¶
func (dst *KVWritesBatchProto) XXX_Merge(src proto.Message)
func (*KVWritesBatchProto) XXX_Size ¶
func (m *KVWritesBatchProto) XXX_Size() int
func (*KVWritesBatchProto) XXX_Unmarshal ¶
func (m *KVWritesBatchProto) XXX_Unmarshal(b []byte) error
type LevelDBCommonStorageTestEnv ¶
type LevelDBCommonStorageTestEnv struct {
// contains filtered or unexported fields
}
LevelDBCommonStorageTestEnv implements TestEnv interface for leveldb based storage
func (*LevelDBCommonStorageTestEnv) Cleanup ¶
func (env *LevelDBCommonStorageTestEnv) Cleanup()
Cleanup implements corresponding function from interface TestEnv
func (*LevelDBCommonStorageTestEnv) GetDBHandle ¶
func (env *LevelDBCommonStorageTestEnv) GetDBHandle(id string) DB
GetDBHandle implements corresponding function from interface TestEnv
func (*LevelDBCommonStorageTestEnv) GetName ¶
func (env *LevelDBCommonStorageTestEnv) GetName() string
GetName implements corresponding function from interface TestEnv
func (*LevelDBCommonStorageTestEnv) Init ¶
func (env *LevelDBCommonStorageTestEnv) Init(t testing.TB)
Init implements corresponding function from interface TestEnv
type PubUpdateBatch ¶
type PubUpdateBatch struct {
*statedb.UpdateBatch
}
PubUpdateBatch contains update for the public data
func NewPubUpdateBatch ¶
func NewPubUpdateBatch() *PubUpdateBatch
NewPubUpdateBatch creates an empty PubUpdateBatch
type PvtKVWrite ¶
PvtKVWrite encloses Key, IsDelete, Value, and Version components
type PvtUpdateBatch ¶
type PvtUpdateBatch struct {
UpdateMap
}
PvtUpdateBatch contains updates for the private data
func NewPvtUpdateBatch ¶
func NewPvtUpdateBatch() *PvtUpdateBatch
NewPvtUpdateBatch creates an empty PvtUpdateBatch
func (PvtUpdateBatch) ToCompositeKeyMap ¶
func (p PvtUpdateBatch) ToCompositeKeyMap() PvtdataCompositeKeyMap
ToCompositeKeyMap rearranges the update batch data in the form of a single map
type PvtdataCompositeKey ¶
PvtdataCompositeKey encloses Namespace, CollectionName and Key components
type PvtdataCompositeKeyMap ¶
type PvtdataCompositeKeyMap map[PvtdataCompositeKey]*statedb.VersionedValue
PvtdataCompositeKeyMap is a map of PvtdataCompositeKey to VersionedValue
type UpdateBatch ¶
type UpdateBatch struct { PubUpdates *PubUpdateBatch HashUpdates *HashedUpdateBatch PvtUpdates *PvtUpdateBatch }
UpdateBatch encapsulates the updates to Public, Private, and Hashed data. This is expected to contain a consistent set of updates
func NewUpdateBatch ¶
func NewUpdateBatch() *UpdateBatch
NewUpdateBatch creates and empty UpdateBatch
type UpdateMap ¶
type UpdateMap map[string]nsBatch
UpdateMap maintains entries of tuple <Namespace, UpdatesForNamespace>
func (UpdateMap) Contains ¶
Contains returns true if the given <ns,coll,key> tuple is present in the batch
func (UpdateMap) Delete ¶
Delete adds a delete marker in the batch for a given combination of namespace and collection name
func (UpdateMap) Get ¶
func (b UpdateMap) Get(ns, coll, key string) *statedb.VersionedValue
Get retrieves the value from the batch for a given combination of namespace and collection name
type UpdatesBytesBuilder ¶
type UpdatesBytesBuilder struct { }
func (*UpdatesBytesBuilder) DeterministicBytesForPubAndHashUpdates ¶
func (bb *UpdatesBytesBuilder) DeterministicBytesForPubAndHashUpdates(u *UpdateBatch) ([]byte, error)
DeterministicBytesForPubAndHashUpdates constructs the bytes for a given UpdateBatch while constructing the bytes, it considers only public writes and hashed writes for the collections. For achieving the determinism, it constructs a slice of proto messages of type 'KVWriteProto'. In the slice, all the writes for a namespace "ns1" appear before the writes for another namespace "ns2" if "ns1" < "ns2" (lexicographically). Within a namespace, all the public writes appear before the collection writes. Like namespaces, the collections writes within a namespace appear in the order of lexicographical order. If an entry has the same namespace as its preceding entry, the namespace field is skipped. A Similar treatment is given to the repetitive entries for a collection within a namespace. For illustration, see the corresponding unit tests