[offchain] Support for sign & verify for crypto keys (#3023)

* Implement sign & verify.

* Use phrases and password.

* Sign & verify with authority keys.

* Fix tests.

* WiP

* WiP

* Allow the caller to decide on 'CryptoKind'.

* Remove TODO.

* Make seed private back.

* Fix non-std build and bump version.

* Use Into<u32> instead of asses.

* Add missing typedef.
This commit is contained in:
Tomasz Drwięga
2019-07-09 17:09:14 +02:00
committed by Gavin Wood
parent ed630e5eda
commit e729dbabbe
22 changed files with 647 additions and 178 deletions
+17 -6
View File
@@ -79,7 +79,7 @@ impl client::backend::OffchainStorage for LocalStorage {
&mut self,
prefix: &[u8],
item_key: &[u8],
old_value: &[u8],
old_value: Option<&[u8]>,
new_value: &[u8],
) -> bool {
let key: Vec<u8> = prefix.iter().chain(item_key).cloned().collect();
@@ -91,11 +91,10 @@ impl client::backend::OffchainStorage for LocalStorage {
let is_set;
{
let _key_guard = key_lock.lock();
is_set = self.db.get(columns::OFFCHAIN, &key)
let val = self.db.get(columns::OFFCHAIN, &key)
.ok()
.and_then(|x| x)
.map(|v| &*v == old_value)
.unwrap_or(true);
.and_then(|x| x);
is_set = val.as_ref().map(|x| &**x) == old_value;
if is_set {
self.set(prefix, item_key, new_value)
@@ -130,8 +129,20 @@ mod tests {
storage.set(prefix, key, value);
assert_eq!(storage.get(prefix, key), Some(value.to_vec()));
assert_eq!(storage.compare_and_set(prefix, key, value, b"asd"), true);
assert_eq!(storage.compare_and_set(prefix, key, Some(value), b"asd"), true);
assert_eq!(storage.get(prefix, key), Some(b"asd".to_vec()));
assert!(storage.locks.lock().is_empty(), "Locks map should be empty!");
}
#[test]
fn should_compare_and_set_on_empty_field() {
let mut storage = LocalStorage::new_test();
let prefix = b"prefix";
let key = b"key";
assert_eq!(storage.compare_and_set(prefix, key, None, b"asd"), true);
assert_eq!(storage.get(prefix, key), Some(b"asd".to_vec()));
assert!(storage.locks.lock().is_empty(), "Locks map should be empty!");
}
}
+1 -1
View File
@@ -213,7 +213,7 @@ pub trait OffchainStorage: Clone + Send + Sync {
&mut self,
prefix: &[u8],
key: &[u8],
old_value: &[u8],
old_value: Option<&[u8]>,
new_value: &[u8],
) -> bool;
}
+19 -11
View File
@@ -794,19 +794,23 @@ impl backend::OffchainStorage for OffchainStorage {
&mut self,
prefix: &[u8],
key: &[u8],
old_value: &[u8],
old_value: Option<&[u8]>,
new_value: &[u8],
) -> bool {
use std::collections::hash_map::Entry;
let key = prefix.iter().chain(key).cloned().collect();
let mut set = false;
self.storage.entry(key).and_modify(|val| {
if val.as_slice() == old_value {
*val = new_value.to_vec();
set = true;
}
});
set
match self.storage.entry(key) {
Entry::Vacant(entry) => if old_value.is_none() {
entry.insert(new_value.to_vec());
true
} else { false },
Entry::Occupied(ref mut entry) if Some(entry.get().as_slice()) == old_value => {
entry.insert(new_value.to_vec());
true
},
_ => false,
}
}
}
@@ -845,9 +849,13 @@ mod tests {
assert_eq!(storage.get(b"A", b"B"), Some(b"C".to_vec()));
assert_eq!(storage.get(b"B", b"A"), None);
storage.compare_and_set(b"A", b"B", b"X", b"D");
storage.compare_and_set(b"A", b"B", Some(b"X"), b"D");
assert_eq!(storage.get(b"A", b"B"), Some(b"C".to_vec()));
storage.compare_and_set(b"A", b"B", b"C", b"D");
storage.compare_and_set(b"A", b"B", Some(b"C"), b"D");
assert_eq!(storage.get(b"A", b"B"), Some(b"D".to_vec()));
assert!(!storage.compare_and_set(b"B", b"A", Some(b""), b"Y"));
assert!(storage.compare_and_set(b"B", b"A", None, b"X"));
assert_eq!(storage.get(b"B", b"A"), Some(b"X".to_vec()));
}
}