Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
irmago
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
IRMA
Github mirrors
irmago
Commits
f3a6e18d
Commit
f3a6e18d
authored
Jan 23, 2020
by
Ivar Derksen
Committed by
Sietse Ringers
Feb 05, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Do combined store calls in one transaction
parent
41996fd5
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
86 additions
and
73 deletions
+86
-73
irmaclient/client.go
irmaclient/client.go
+43
-32
irmaclient/storage.go
irmaclient/storage.go
+40
-37
irmaclient/updates.go
irmaclient/updates.go
+3
-4
No files found.
irmaclient/client.go
View file @
f3a6e18d
...
...
@@ -229,13 +229,17 @@ func (client *Client) addCredential(cred *credential) (err error) {
if
!
id
.
Empty
()
{
if
cred
.
CredentialType
()
.
IsSingleton
{
for
len
(
client
.
attrs
(
id
))
!=
0
{
_
=
client
.
remove
(
id
,
0
,
false
)
if
err
=
client
.
remove
(
id
,
0
,
false
);
err
!=
nil
{
return
}
}
}
for
i
:=
len
(
client
.
attrs
(
id
))
-
1
;
i
>=
0
;
i
--
{
// Go backwards through array because remove manipulates it
if
client
.
attrs
(
id
)[
i
]
.
EqualsExceptMetadata
(
cred
.
AttributeList
())
{
_
=
client
.
remove
(
id
,
i
,
false
)
if
err
=
client
.
remove
(
id
,
i
,
false
);
err
!=
nil
{
return
}
}
}
}
...
...
@@ -250,11 +254,12 @@ func (client *Client) addCredential(cred *credential) (err error) {
client
.
credentialsCache
[
id
][
counter
]
=
cred
}
if
err
=
client
.
storage
.
StoreSignature
(
cred
);
err
!=
nil
{
return
}
err
=
client
.
storage
.
StoreAttributes
(
id
,
client
.
attributes
[
id
])
return
return
client
.
storage
.
DoStoreTransaction
(
func
(
tx
*
transaction
)
error
{
if
err
=
client
.
storage
.
TxStoreSignature
(
tx
,
cred
);
err
!=
nil
{
return
err
}
return
client
.
storage
.
TxStoreAttributes
(
tx
,
id
,
client
.
attributes
[
id
])
})
}
func
generateSecretKey
()
(
*
secretKey
,
error
)
{
...
...
@@ -276,33 +281,36 @@ func (client *Client) remove(id irma.CredentialTypeIdentifier, index int, storeL
attrs
:=
list
[
index
]
client
.
attributes
[
id
]
=
append
(
list
[
:
index
],
list
[
index
+
1
:
]
...
)
if
err
:=
client
.
storage
.
StoreAttributes
(
id
,
client
.
attributes
[
id
]);
err
!=
nil
{
removed
:=
map
[
irma
.
CredentialTypeIdentifier
][]
irma
.
TranslatedString
{}
removed
[
id
]
=
attrs
.
Strings
()
err
:=
client
.
storage
.
DoStoreTransaction
(
func
(
tx
*
transaction
)
error
{
if
err
:=
client
.
storage
.
TxDeleteSignature
(
tx
,
attrs
);
err
!=
nil
{
return
err
}
if
err
:=
client
.
storage
.
TxStoreAttributes
(
tx
,
id
,
client
.
attributes
[
id
]);
err
!=
nil
{
return
err
}
if
storeLog
{
return
client
.
storage
.
TxAddLogEntry
(
tx
,
&
LogEntry
{
Type
:
ActionRemoval
,
Time
:
irma
.
Timestamp
(
time
.
Now
()),
Removed
:
removed
,
})
}
return
nil
})
if
err
!=
nil
{
return
err
}
// Remove credential
// Remove credential
from cache
if
creds
,
exists
:=
client
.
credentialsCache
[
id
];
exists
{
if
_
,
exists
:=
creds
[
index
];
exists
{
delete
(
creds
,
index
)
client
.
credentialsCache
[
id
]
=
creds
}
}
// Remove signature from storage
if
err
:=
client
.
storage
.
DeleteSignature
(
attrs
);
err
!=
nil
{
return
err
}
removed
:=
map
[
irma
.
CredentialTypeIdentifier
][]
irma
.
TranslatedString
{}
removed
[
id
]
=
attrs
.
Strings
()
if
storeLog
{
return
client
.
storage
.
AddLogEntry
(
&
LogEntry
{
Type
:
ActionRemoval
,
Time
:
irma
.
Timestamp
(
time
.
Now
()),
Removed
:
removed
,
})
}
return
nil
}
...
...
@@ -334,19 +342,22 @@ func (client *Client) RemoveAllCredentials() error {
}
}
client
.
attributes
=
map
[
irma
.
CredentialTypeIdentifier
][]
*
irma
.
AttributeList
{}
if
err
:=
client
.
storage
.
DeleteAllAttributes
();
err
!=
nil
{
return
err
}
if
err
:=
client
.
storage
.
DeleteAllSignatures
();
err
!=
nil
{
return
err
}
logentry
:=
&
LogEntry
{
Type
:
ActionRemoval
,
Time
:
irma
.
Timestamp
(
time
.
Now
()),
Removed
:
removed
,
}
return
client
.
storage
.
AddLogEntry
(
logentry
)
return
client
.
storage
.
DoStoreTransaction
(
func
(
tx
*
transaction
)
error
{
if
err
:=
client
.
storage
.
TxDeleteAllAttributes
(
tx
);
err
!=
nil
{
return
err
}
if
err
:=
client
.
storage
.
TxDeleteAllSignatures
(
tx
);
err
!=
nil
{
return
err
}
return
client
.
storage
.
TxAddLogEntry
(
tx
,
logentry
)
})
}
// Attribute and credential getter methods
...
...
irmaclient/storage.go
View file @
f3a6e18d
...
...
@@ -23,6 +23,10 @@ type storage struct {
Configuration
*
irma
.
Configuration
}
type
transaction
struct
{
*
bbolt
.
Tx
}
// Filenames
const
databaseFile
=
"db"
...
...
@@ -60,7 +64,7 @@ func (s *storage) Close() error {
return
s
.
db
.
Close
()
}
func
(
s
*
storage
)
txStore
(
tx
*
bbolt
.
Tx
,
key
string
,
value
interface
{},
bucketName
string
)
error
{
func
(
s
*
storage
)
txStore
(
tx
*
transaction
,
bucketName
string
,
key
string
,
value
interface
{}
)
error
{
b
,
err
:=
tx
.
CreateBucketIfNotExists
([]
byte
(
bucketName
))
if
err
!=
nil
{
return
err
...
...
@@ -73,7 +77,7 @@ func (s *storage) txStore(tx *bbolt.Tx, key string, value interface{}, bucketNam
return
b
.
Put
([]
byte
(
key
),
btsValue
)
}
func
(
s
*
storage
)
txDelete
(
tx
*
bbolt
.
Tx
,
key
string
,
bucketName
string
)
error
{
func
(
s
*
storage
)
txDelete
(
tx
*
transaction
,
key
string
,
bucketName
string
)
error
{
b
,
err
:=
tx
.
CreateBucketIfNotExists
([]
byte
(
bucketName
))
if
err
!=
nil
{
return
err
...
...
@@ -82,12 +86,13 @@ func (s *storage) txDelete(tx *bbolt.Tx, key string, bucketName string) error {
return
b
.
Delete
([]
byte
(
key
))
}
func
(
s
*
storage
)
txLoad
(
tx
*
bbolt
.
Tx
,
key
string
,
dest
interface
{},
bucketName
string
)
(
found
bool
,
err
error
)
{
func
(
s
*
storage
)
txLoad
(
tx
*
transaction
,
key
string
,
dest
interface
{},
bucketName
string
)
(
found
bool
,
err
error
)
{
b
:=
tx
.
Bucket
([]
byte
(
bucketName
))
if
b
==
nil
{
return
false
,
nil
}
bts
:=
b
.
Get
([]
byte
(
key
))
b
.
Sequence
()
if
bts
==
nil
{
return
false
,
nil
}
...
...
@@ -96,88 +101,86 @@ func (s *storage) txLoad(tx *bbolt.Tx, key string, dest interface{}, bucketName
func
(
s
*
storage
)
load
(
key
string
,
dest
interface
{},
bucketName
string
)
(
found
bool
,
err
error
)
{
err
=
s
.
db
.
View
(
func
(
tx
*
bbolt
.
Tx
)
error
{
found
,
err
=
s
.
txLoad
(
tx
,
key
,
dest
,
bucketName
)
found
,
err
=
s
.
txLoad
(
&
transaction
{
tx
}
,
key
,
dest
,
bucketName
)
return
err
})
return
}
func
(
s
*
storage
)
D
eleteSignature
(
attrs
*
irma
.
AttributeList
)
error
{
func
(
s
*
storage
)
D
oStoreTransaction
(
f
func
(
*
transaction
)
error
)
error
{
return
s
.
db
.
Update
(
func
(
tx
*
bbolt
.
Tx
)
error
{
return
s
.
txDelete
(
tx
,
attrs
.
Hash
(),
signaturesBucket
)
return
f
(
&
transaction
{
tx
}
)
})
}
func
(
s
*
storage
)
DeleteAllSignatures
()
error
{
return
s
.
db
.
Update
(
func
(
tx
*
bbolt
.
Tx
)
error
{
return
tx
.
DeleteBucket
([]
byte
(
signaturesBucket
))
})
func
(
s
*
storage
)
TxDeleteSignature
(
tx
*
transaction
,
attrs
*
irma
.
AttributeList
)
error
{
return
s
.
txDelete
(
tx
,
attrs
.
Hash
(),
signaturesBucket
)
}
func
(
s
*
storage
)
StoreSignature
(
cred
*
credential
)
error
{
return
s
.
db
.
Update
(
func
(
tx
*
bbolt
.
Tx
)
error
{
return
s
.
TxStoreSignature
(
tx
,
cred
.
AttributeList
()
.
Hash
(),
cred
.
Signature
)
})
func
(
s
*
storage
)
TxDeleteAllSignatures
(
tx
*
transaction
)
error
{
return
tx
.
DeleteBucket
([]
byte
(
signaturesBucket
))
}
func
(
s
*
storage
)
TxStoreSignature
(
tx
*
transaction
,
cred
*
credential
)
error
{
return
s
.
TxStoreCLSignature
(
tx
,
cred
.
AttributeList
()
.
Hash
(),
cred
.
Signature
)
}
func
(
s
*
storage
)
TxStore
Signature
(
tx
*
bbolt
.
Tx
,
credHash
string
,
sig
*
gabi
.
CLSignature
)
error
{
func
(
s
*
storage
)
TxStore
CLSignature
(
tx
*
transaction
,
credHash
string
,
sig
*
gabi
.
CLSignature
)
error
{
// We take the SHA256 hash over all attributes as the bucket key for the signature.
// This means that of the signatures of two credentials that have identical attributes
// only one gets stored, one overwriting the other - but that doesn't
// matter, because either one of the signatures is valid over both attribute lists,
// so keeping one of them suffices.
return
s
.
txStore
(
tx
,
credHash
,
sig
,
signaturesBucket
)
return
s
.
txStore
(
tx
,
signaturesBucket
,
credHash
,
sig
)
}
func
(
s
*
storage
)
StoreSecretKey
(
sk
*
secretKey
)
error
{
return
s
.
db
.
Update
(
func
(
tx
*
bbolt
.
Tx
)
error
{
return
s
.
DoStoreTransaction
(
func
(
tx
*
transaction
)
error
{
return
s
.
TxStoreSecretKey
(
tx
,
sk
)
})
}
func
(
s
*
storage
)
TxStoreSecretKey
(
tx
*
bbolt
.
Tx
,
sk
*
secretKey
)
error
{
return
s
.
txStore
(
tx
,
skKey
,
sk
,
userdataBucket
)
func
(
s
*
storage
)
TxStoreSecretKey
(
tx
*
transaction
,
sk
*
secretKey
)
error
{
return
s
.
txStore
(
tx
,
userdataBucket
,
skKey
,
sk
)
}
func
(
s
*
storage
)
StoreAttributes
(
credTypeID
irma
.
CredentialTypeIdentifier
,
attrlistlist
[]
*
irma
.
AttributeList
)
error
{
return
s
.
db
.
Update
(
func
(
tx
*
bbolt
.
Tx
)
error
{
return
s
.
DoStoreTransaction
(
func
(
tx
*
transaction
)
error
{
return
s
.
TxStoreAttributes
(
tx
,
credTypeID
,
attrlistlist
)
})
}
func
(
s
*
storage
)
TxStoreAttributes
(
tx
*
bbolt
.
Tx
,
credTypeID
irma
.
CredentialTypeIdentifier
,
func
(
s
*
storage
)
TxStoreAttributes
(
tx
*
transaction
,
credTypeID
irma
.
CredentialTypeIdentifier
,
attrlistlist
[]
*
irma
.
AttributeList
)
error
{
// If no credentials are left of a certain type, the full entry can be deleted.
if
len
(
attrlistlist
)
==
0
{
return
s
.
txDelete
(
tx
,
credTypeID
.
String
(),
attributesBucket
)
}
return
s
.
txStore
(
tx
,
credTypeID
.
String
(),
attrlistlist
,
attributesBucke
t
)
return
s
.
txStore
(
tx
,
attributesBucket
,
credTypeID
.
String
(),
attrlistlis
t
)
}
func
(
s
*
storage
)
DeleteAllAttributes
()
error
{
return
s
.
db
.
Update
(
func
(
tx
*
bbolt
.
Tx
)
error
{
return
tx
.
DeleteBucket
([]
byte
(
attributesBucket
))
})
func
(
s
*
storage
)
TxDeleteAllAttributes
(
tx
*
transaction
)
error
{
return
tx
.
DeleteBucket
([]
byte
(
attributesBucket
))
}
func
(
s
*
storage
)
StoreKeyshareServers
(
keyshareServers
map
[
irma
.
SchemeManagerIdentifier
]
*
keyshareServer
)
error
{
return
s
.
db
.
Update
(
func
(
tx
*
bbolt
.
Tx
)
error
{
return
s
.
DoStoreTransaction
(
func
(
tx
*
transaction
)
error
{
return
s
.
TxStoreKeyshareServers
(
tx
,
keyshareServers
)
})
}
func
(
s
*
storage
)
TxStoreKeyshareServers
(
tx
*
bbolt
.
Tx
,
keyshareServers
map
[
irma
.
SchemeManagerIdentifier
]
*
keyshareServer
)
error
{
return
s
.
txStore
(
tx
,
kssKey
,
keyshareServers
,
userdataBucket
)
func
(
s
*
storage
)
TxStoreKeyshareServers
(
tx
*
transaction
,
keyshareServers
map
[
irma
.
SchemeManagerIdentifier
]
*
keyshareServer
)
error
{
return
s
.
txStore
(
tx
,
userdataBucket
,
kssKey
,
keyshareServers
)
}
func
(
s
*
storage
)
AddLogEntry
(
entry
*
LogEntry
)
error
{
return
s
.
db
.
Update
(
func
(
tx
*
bbolt
.
Tx
)
error
{
return
s
.
TxAddLogEntry
(
tx
,
entry
)
return
s
.
TxAddLogEntry
(
&
transaction
{
tx
}
,
entry
)
})
}
func
(
s
*
storage
)
TxAddLogEntry
(
tx
*
bbolt
.
Tx
,
entry
*
LogEntry
)
error
{
func
(
s
*
storage
)
TxAddLogEntry
(
tx
*
transaction
,
entry
*
LogEntry
)
error
{
b
,
err
:=
tx
.
CreateBucketIfNotExists
([]
byte
(
logsBucket
))
if
err
!=
nil
{
return
err
...
...
@@ -200,23 +203,23 @@ func (s *storage) logEntryKeyToBytes(id uint64) []byte {
}
func
(
s
*
storage
)
StorePreferences
(
prefs
Preferences
)
error
{
return
s
.
db
.
Update
(
func
(
tx
*
bbolt
.
Tx
)
error
{
return
s
.
DoStoreTransaction
(
func
(
tx
*
transaction
)
error
{
return
s
.
TxStorePreferences
(
tx
,
prefs
)
})
}
func
(
s
*
storage
)
TxStorePreferences
(
tx
*
bbolt
.
Tx
,
prefs
Preferences
)
error
{
return
s
.
txStore
(
tx
,
preferencesKey
,
prefs
,
userdataBucket
)
func
(
s
*
storage
)
TxStorePreferences
(
tx
*
transaction
,
prefs
Preferences
)
error
{
return
s
.
txStore
(
tx
,
userdataBucket
,
preferencesKey
,
prefs
)
}
func
(
s
*
storage
)
StoreUpdates
(
updates
[]
update
)
(
err
error
)
{
return
s
.
db
.
Update
(
func
(
tx
*
bbolt
.
Tx
)
error
{
return
s
.
DoStoreTransaction
(
func
(
tx
*
transaction
)
error
{
return
s
.
TxStoreUpdates
(
tx
,
updates
)
})
}
func
(
s
*
storage
)
TxStoreUpdates
(
tx
*
bbolt
.
Tx
,
updates
[]
update
)
error
{
return
s
.
txStore
(
tx
,
u
pdatesKey
,
updates
,
userdataBucket
)
func
(
s
*
storage
)
TxStoreUpdates
(
tx
*
transaction
,
updates
[]
update
)
error
{
return
s
.
txStore
(
tx
,
u
serdataBucket
,
updatesKey
,
updates
)
}
func
(
s
*
storage
)
LoadSignature
(
attrs
*
irma
.
AttributeList
)
(
signature
*
gabi
.
CLSignature
,
err
error
)
{
...
...
irmaclient/updates.go
View file @
f3a6e18d
...
...
@@ -6,7 +6,6 @@ import (
"time"
"github.com/privacybydesign/irmago"
"go.etcd.io/bbolt"
)
// This file contains the update mechanism for Client
...
...
@@ -51,7 +50,7 @@ var clientUpdates = []func(client *Client) error{
}
// Open one bolt transaction to process all our log entries in
err
=
client
.
storage
.
db
.
Update
(
func
(
tx
*
bbolt
.
Tx
)
error
{
err
=
client
.
storage
.
DoStoreTransaction
(
func
(
tx
*
transaction
)
error
{
for
_
,
log
:=
range
logs
{
// As log.Request is a json.RawMessage it would not get updated to the new session request
// format by re-marshaling the containing struct, as normal struct members would,
...
...
@@ -120,7 +119,7 @@ var clientUpdates = []func(client *Client) error{
return
err
}
return
client
.
storage
.
db
.
Update
(
func
(
tx
*
bbolt
.
Tx
)
error
{
return
client
.
storage
.
DoStoreTransaction
(
func
(
tx
*
transaction
)
error
{
if
err
=
client
.
storage
.
TxStoreSecretKey
(
tx
,
sk
);
err
!=
nil
{
return
err
}
...
...
@@ -130,7 +129,7 @@ var clientUpdates = []func(client *Client) error{
}
}
for
hash
,
sig
:=
range
sigs
{
err
=
client
.
storage
.
TxStoreSignature
(
tx
,
hash
,
sig
)
err
=
client
.
storage
.
TxStore
CL
Signature
(
tx
,
hash
,
sig
)
if
err
!=
nil
{
return
err
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment