Skip to content

Commit

Permalink
Refactored wallet registry
Browse files Browse the repository at this point in the history
Extracted kvs functionality to be wallet specific

Signed-off-by: Alexandros Filios <alexandros.filios@ibm.com>
  • Loading branch information
alexandrosfilios committed Jan 11, 2024
1 parent ad5e988 commit 715ac28
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 105 deletions.
6 changes: 2 additions & 4 deletions token/core/fabtoken/driver/driver.go
Expand Up @@ -97,12 +97,11 @@ func (d *Driver) NewTokenService(sp view.ServiceProvider, publicParamsFetcher dr
Namespace: namespace,
}
ws := fabtoken.NewWalletService(
tmsID,
msp.NewSigService(view.GetSigService(sp)),
identity.NewProvider(view.GetSigService(sp), view.GetEndpointService(sp), fscIdentity, fabtoken.NewEnrollmentIDDeserializer(), wallets),
qe,
fabtoken.NewDeserializer(),
kvs.GetService(sp),
identity.NewKVSStorage(kvs.GetService(sp), tmsID),
)

service := fabtoken.NewService(
Expand Down Expand Up @@ -196,12 +195,11 @@ func (d *Driver) NewWalletService(sp view.ServiceProvider, networkID string, cha
}
// wallet service
ws := fabtoken.NewWalletService(
tmsID,
msp.NewSigService(view.GetSigService(sp)),
identity.NewProvider(view.GetSigService(sp), nil, nil, fabtoken.NewEnrollmentIDDeserializer(), wallets),
nil,
fabtoken.NewDeserializer(),
kvs.GetService(sp),
identity.NewKVSStorage(kvs.GetService(sp), tmsID),
)

return ws, nil
Expand Down
10 changes: 4 additions & 6 deletions token/core/fabtoken/wallet.go
Expand Up @@ -9,7 +9,6 @@ package fabtoken
import (
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/hash"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/view"
token2 "github.com/hyperledger-labs/fabric-token-sdk/token"
"github.com/hyperledger-labs/fabric-token-sdk/token/core/identity"
"github.com/hyperledger-labs/fabric-token-sdk/token/core/identity/msp/common"
"github.com/hyperledger-labs/fabric-token-sdk/token/driver"
Expand All @@ -34,21 +33,20 @@ type WalletService struct {
}

func NewWalletService(
tmsID token2.TMSID,
SignerService common.SignerService,
identityProvider driver.IdentityProvider,
walletServiceBacked WalletServiceBacked,
Deserializer driver.Deserializer,
kvs KVS,
store identity.Storage,
) *WalletService {
return &WalletService{
SignerService: SignerService,
identityProvider: identityProvider,
WalletServiceBacked: walletServiceBacked,
Deserializer: Deserializer,
OwnerWalletsRegistry: identity.NewWalletsRegistry(tmsID, identityProvider, driver.OwnerRole, kvs),
IssuerWalletsRegistry: identity.NewWalletsRegistry(tmsID, identityProvider, driver.IssuerRole, kvs),
AuditorWalletsRegistry: identity.NewWalletsRegistry(tmsID, identityProvider, driver.AuditorRole, kvs),
OwnerWalletsRegistry: identity.NewWalletsRegistry(identityProvider, driver.OwnerRole, store),
IssuerWalletsRegistry: identity.NewWalletsRegistry(identityProvider, driver.IssuerRole, store),
AuditorWalletsRegistry: identity.NewWalletsRegistry(identityProvider, driver.AuditorRole, store),
}
}

Expand Down
125 changes: 42 additions & 83 deletions token/core/identity/registry.go
Expand Up @@ -11,8 +11,6 @@ import (
"strings"
"sync"

"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/kvs"

"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/hash"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/view"
"github.com/hyperledger-labs/fabric-token-sdk/token"
Expand All @@ -21,37 +19,32 @@ import (
"go.uber.org/zap/zapcore"
)

type KVS interface {
Exists(id string) bool
Put(id string, state interface{}) error
Get(id string, state interface{}) error
GetByPartialCompositeID(prefix string, attrs []string) (kvs.Iterator, error)
}

type WalletEntry struct {
ID string
Prefix string
Wallet driver.Wallet `json:"-"`
type Storage interface {
StoreWalletID(wID WalletID) error
GetWalletID(identity view.Identity) (WalletID, error)
GetWalletIDs() ([]WalletID, error)
StoreIdentity(identity view.Identity, wID WalletID, meta any) error
IdentityExists(identity view.Identity, wID WalletID) bool
LoadMeta(identity view.Identity, meta any) error
}

type WalletsRegistry struct {
ID token.TMSID
IdentityProvider driver.IdentityProvider
IdentityRole driver.IdentityRole
KVS KVS
Store Storage

sync.RWMutex
Wallets map[string]*WalletEntry
Wallets map[string]driver.Wallet
}

// NewWalletsRegistry returns a new wallets registry for the passed parameters
func NewWalletsRegistry(id token.TMSID, identityProvider driver.IdentityProvider, identityRole driver.IdentityRole, KVS KVS) *WalletsRegistry {
func NewWalletsRegistry(identityProvider driver.IdentityProvider, identityRole driver.IdentityRole, store Storage) *WalletsRegistry {
return &WalletsRegistry{
ID: id,
IdentityProvider: identityProvider,
IdentityRole: identityRole,
KVS: KVS,
Wallets: map[string]*WalletEntry{},
Store: store,
Wallets: map[string]driver.Wallet{},
}
}

Expand All @@ -68,15 +61,11 @@ func (r *WalletsRegistry) Lookup(id interface{}) (driver.Wallet, driver.Identity
// give it a second change
passedIdentity, ok := id.(view.Identity)
if ok {
if logger.IsEnabledFor(zapcore.DebugLevel) {
logger.Debugf("lookup failed, check if there is a wallet for identity [%s]", passedIdentity)
}
logger.Debugf("lookup failed, check if there is a wallet for identity [%s]", passedIdentity)
// is this identity registered
wID, err := r.GetWallet(passedIdentity)
wID, err := r.GetWalletID(passedIdentity)
if err == nil && len(wID) != 0 {
if logger.IsEnabledFor(zapcore.DebugLevel) {
logger.Debugf("lookup failed, there is a wallet for identity [%s]: [%s]", passedIdentity, wID)
}
logger.Debugf("lookup failed, there is a wallet for identity [%s]: [%s]", passedIdentity, wID)
// we got a hit
walletID = wID
identity = passedIdentity
Expand All @@ -93,30 +82,24 @@ func (r *WalletsRegistry) Lookup(id interface{}) (driver.Wallet, driver.Identity
wID := walletID
walletEntry, ok := r.Wallets[wID]
if ok {
return walletEntry.Wallet, nil, wID, nil
return walletEntry, nil, wID, nil
}
walletIdentifiers = append(walletIdentifiers, wID)

// give it a second chance
passedIdentity, ok := id.(view.Identity)
if ok {
if logger.IsEnabledFor(zapcore.DebugLevel) {
logger.Debugf("no wallet found, check if there is a wallet for identity [%s]", passedIdentity)
}
logger.Debugf("no wallet found, check if there is a wallet for identity [%s]", passedIdentity)
// is this identity registered
passedWalletID, err := r.GetWallet(passedIdentity)
passedWalletID, err := r.GetWalletID(passedIdentity)
if err == nil && len(passedWalletID) != 0 {
if logger.IsEnabledFor(zapcore.DebugLevel) {
logger.Debugf("no wallet found, there is a wallet for identity [%s]: [%s]", passedIdentity, passedWalletID)
}
logger.Debugf("no wallet found, there is a wallet for identity [%s]: [%s]", passedIdentity, passedWalletID)
// we got a hit
walletEntry, ok = r.Wallets[passedWalletID]
if ok {
return walletEntry.Wallet, nil, passedWalletID, nil
}
if logger.IsEnabledFor(zapcore.DebugLevel) {
logger.Debugf("no wallet found, there is a wallet for identity [%s]: [%s] but it has not been recreated yet", passedIdentity, passedWalletID)
return walletEntry, nil, passedWalletID, nil
}
logger.Debugf("no wallet found, there is a wallet for identity [%s]: [%s] but it has not been recreated yet", passedIdentity, passedWalletID)
}
walletIdentifiers = append(walletIdentifiers, passedWalletID)
}
Expand All @@ -125,17 +108,17 @@ func (r *WalletsRegistry) Lookup(id interface{}) (driver.Wallet, driver.Identity
logger.Debugf("no wallet found for [%s] at [%s]", identity, walletIDToString(wID))
}
if len(identity) != 0 {
identityWID, err := r.GetWallet(identity)
identityWID, err := r.GetWalletID(identity)
if logger.IsEnabledFor(zapcore.DebugLevel) {
logger.Debugf("wallet for identity [%s] -> [%s:%s]", identity, identityWID, err)
}
if err == nil && len(identityWID) != 0 {
w, ok := r.Wallets[identityWID]
if ok {
if logger.IsEnabledFor(zapcore.DebugLevel) {
logger.Debugf("found wallet [%s:%s:%s:%s]", identity, walletID, w.Wallet.ID(), identityWID)
logger.Debugf("found wallet [%s:%s:%s:%s]", identity, walletID, w.ID(), identityWID)
}
return w.Wallet, nil, identityWID, nil
return w, nil, identityWID, nil
}
}
walletIdentifiers = append(walletIdentifiers, identityWID)
Expand Down Expand Up @@ -164,15 +147,10 @@ func (r *WalletsRegistry) Lookup(id interface{}) (driver.Wallet, driver.Identity

// RegisterWallet binds the passed wallet to the passed id
func (r *WalletsRegistry) RegisterWallet(id string, w driver.Wallet) error {
entry := &WalletEntry{
ID: id,
Prefix: fmt.Sprintf("%s-%s-%s-%s", r.ID.Network, r.ID.Channel, r.ID.Namespace, id),
Wallet: w,
}
if err := r.KVS.Put(kvs.CreateCompositeKeyOrPanic("wallets", []string{r.ID.Network, r.ID.Channel, r.ID.Namespace, id}), entry); err != nil {
if err := r.Store.StoreWalletID(id); err != nil {
return errors.WithMessagef(err, "failed to store wallet entry [%s]", id)
}
r.Wallets[id] = entry
r.Wallets[id] = w
return nil
}

Expand All @@ -182,38 +160,25 @@ func (r *WalletsRegistry) RegisterIdentity(identity view.Identity, wID string, m
if logger.IsEnabledFor(zapcore.DebugLevel) {
logger.Debugf("put recipient identity [%s]->[%s]", identity, wID)
}
idHash := identity.Hash()
if err := r.KVS.Put(idHash, wID); err != nil {
return errors.WithMessagef(err, "failed to store identity's wallet [%s]", identity)
}
if meta != nil {
if err := r.KVS.Put("meta"+idHash, meta); err != nil {
return errors.WithMessagef(err, "failed to store identity's metadata [%s]", identity)
}
}
if err := r.KVS.Put(r.Wallets[wID].Prefix+idHash, wID); err != nil {
return errors.WithMessagef(err, "failed to store identity's wallet reference[%s]", identity)
}
return nil
return r.Store.StoreIdentity(identity, wID, meta)
}

// GetIdentityMetadata loads metadata bound to the passed identity into the passed meta argument
func (r *WalletsRegistry) GetIdentityMetadata(identity view.Identity, wID string, meta any) error {
if logger.IsEnabledFor(zapcore.DebugLevel) {
logger.Debugf("get recipient identity metadata [%s]->[%s]", identity, wID)
}
idHash := identity.Hash()
if err := r.KVS.Get("meta"+idHash, meta); err != nil {
if err := r.Store.LoadMeta(identity, meta); err != nil {
return errors.WithMessagef(err, "failed to retrieve identity's metadata [%s]", identity)
}
return nil
}

// GetWallet returns the wallet identifier bound to the passed identity
func (r *WalletsRegistry) GetWallet(identity view.Identity) (string, error) {
var wID string
if err := r.KVS.Get(identity.Hash(), &wID); err != nil {
return "", err
// GetWalletID returns the wallet identifier bound to the passed identity
func (r *WalletsRegistry) GetWalletID(identity view.Identity) (string, error) {
wID, err := r.Store.GetWalletID(identity)
if err != nil {
return "", nil
}
if logger.IsEnabledFor(zapcore.DebugLevel) {
logger.Debugf("wallet [%s] is bound to identity [%s]", wID, identity)
Expand All @@ -224,7 +189,7 @@ func (r *WalletsRegistry) GetWallet(identity view.Identity) (string, error) {
// ContainsIdentity returns true if the passed identity belongs to the passed wallet,
// false otherwise
func (r *WalletsRegistry) ContainsIdentity(identity view.Identity, wID string) bool {
return r.KVS.Exists(r.Wallets[wID].Prefix + identity.Hash())
return r.Store.IdentityExists(identity, wID)
}

// WalletIDs returns the list of owner wallet identifiers
Expand All @@ -233,28 +198,22 @@ func (r *WalletsRegistry) WalletIDs() ([]string, error) {
if err != nil {
return nil, errors.Wrapf(err, "failed to get wallet identifiers from identity provider")
}
it, err := r.KVS.GetByPartialCompositeID("wallets", []string{r.ID.Network, r.ID.Channel, r.ID.Namespace})
if err != nil {
return nil, errors.Wrapf(err, "failed to get wallets iterator")
}
duplicates := map[string]bool{}
for _, id := range walletIDs {
duplicates[id] = true
}

for it.HasNext() {
entry := &WalletEntry{}
_, err := it.Next(entry)
if err != nil {
return nil, errors.Wrapf(err, "failed to get next wallets from iterator")
}
_, found := duplicates[entry.ID]
ids, err := r.Store.GetWalletIDs()
if err != nil {
return nil, errors.Wrapf(err, "failed to get wallets iterator")
}
for _, wID := range ids {
_, found := duplicates[wID]
if !found {
walletIDs = append(walletIDs, entry.ID)
duplicates[entry.ID] = true
walletIDs = append(walletIDs, wID)
duplicates[wID] = true
}
}

return walletIDs, nil
}

Expand Down
4 changes: 2 additions & 2 deletions token/core/identity/registry_test.go
Expand Up @@ -28,10 +28,10 @@ func TestGetWallet(t *testing.T) {

alice := view.Identity("alice")
meta := "meta"
wr := NewWalletsRegistry(token.TMSID{Network: "testnetwork", Channel: "testchannel", Namespace: "tns"}, nil, driver.OwnerRole, kvstore)
wr := NewWalletsRegistry(nil, driver.OwnerRole, NewKVSStorage(kvstore, token.TMSID{Network: "testnetwork", Channel: "testchannel", Namespace: "tns"}))
wr.RegisterWallet("hello", nil)
assert.NoError(t, wr.RegisterIdentity(alice, "hello", meta))
wID, err := wr.GetWallet(alice)
wID, err := wr.GetWalletID(alice)
assert.NoError(t, err)
assert.Equal(t, "hello", wID)
var meta2 string
Expand Down

0 comments on commit 715ac28

Please sign in to comment.