Skip to content

Commit

Permalink
[feature] hyperledger-iroha#2434: FFI bindgen library (hyperledger-ir…
Browse files Browse the repository at this point in the history
…oha#2314)

Signed-off-by: Marin Veršić <marin.versic101@gmail.com>
  • Loading branch information
mversic committed Sep 9, 2022
1 parent 9c5c531 commit 82fa83f
Show file tree
Hide file tree
Showing 46 changed files with 2,975 additions and 1,576 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 1 addition & 9 deletions cli/src/torii/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -747,14 +747,6 @@ async fn blocks_stream() {
assert_eq!(block.header().height, BLOCK_COUNT as u64 + 1);
}

/// Returns the a map of a form `domain_name -> domain`, for initial domains.
fn domains(
configuration: &crate::config::Configuration,
) -> eyre::Result<impl Iterator<Item = Domain>> {
let key = configuration.genesis.account_public_key.clone();
Ok([Domain::from(GenesisDomain::new(key))].into_iter())
}

#[test]
fn hash_should_be_the_same() {
prepare_test_for_nextest!();
Expand Down Expand Up @@ -786,7 +778,7 @@ fn hash_should_be_the_same() {
AcceptedTransaction::from_transaction(signed_tx, &tx_limits).expect("Failed to accept.");
let accepted_tx_hash = accepted_tx.hash();
let wsv = Arc::new(WorldStateView::new(World::with(
domains(&config).unwrap(),
crate::domains(&config),
BTreeSet::new(),
)));
let valid_tx_hash = TransactionValidator::new(
Expand Down
4 changes: 2 additions & 2 deletions crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ default = ["std"]
std = ["ursa"]
# Force static linking
vendored = ["openssl-sys"]
# Expose FFI API to facilitate dynamic linking
ffi_api = ["iroha_ffi"]
# Generate extern functions callable via FFI
ffi = ["iroha_ffi"]

[dependencies]
iroha_primitives = { path = "../primitives", version = "=2.0.0-pre-rc.5", default-features = false }
Expand Down
4 changes: 2 additions & 2 deletions crypto/src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,13 @@ impl<T: IntoSchema> IntoSchema for HashOf<T> {
format!("{}::HashOf<{}>", module_path!(), T::type_name())
}
fn schema(map: &mut MetaMap) {
Hash::schema(map);

map.entry(Self::type_name()).or_insert_with(|| {
Metadata::Tuple(UnnamedFieldsMeta {
types: vec![Hash::type_name()],
})
});

Hash::schema(map);
}
}

Expand Down
56 changes: 44 additions & 12 deletions crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ pub use base64;
use derive_more::{DebugCustom, Display};
use getset::Getters;
pub use hash::*;
#[cfg(feature = "ffi")]
use iroha_ffi::{ffi_export, IntoFfi, TryFromFfi};
use iroha_primitives::conststr::ConstString;
use iroha_schema::IntoSchema;
pub use merkle::MerkleTree;
Expand Down Expand Up @@ -62,7 +64,9 @@ pub struct NoSuchAlgorithm;
impl std::error::Error for NoSuchAlgorithm {}

/// Algorithm for hashing
#[cfg_attr(feature = "ffi", derive(IntoFfi, TryFromFfi))]
#[derive(Debug, Display, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum Algorithm {
/// Ed25519
#[display(fmt = "{}", "ED_25519")]
Expand Down Expand Up @@ -161,6 +165,7 @@ impl KeyGenConfiguration {
}

/// Pair of Public and Private keys.
#[cfg_attr(feature = "ffi", derive(IntoFfi, TryFromFfi))]
#[derive(Debug, Clone, PartialEq, Eq, Getters, Serialize)]
#[getset(get = "pub")]
pub struct KeyPair {
Expand Down Expand Up @@ -359,21 +364,26 @@ impl From<multihash::ConvertError> for KeyParseError {
impl std::error::Error for KeyParseError {}

/// Public Key used in signatures.
#[derive(DebugCustom, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters, Encode, IntoSchema)]
#[getset(get = "pub")]
#[derive(DebugCustom, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, IntoSchema)]
#[cfg_attr(feature = "ffi", derive(IntoFfi, TryFromFfi))]
#[debug(
fmt = "{{ digest: {digest_function}, payload: {} }}",
"hex::encode_upper(payload.as_slice())"
)]
pub struct PublicKey {
/// Digest function
#[getset(skip)]
digest_function: ConstString,
/// payload of key
payload: Vec<u8>,
}

#[cfg_attr(feature = "ffi", ffi_export)]
impl PublicKey {
/// Key payload
pub fn payload(&self) -> &[u8] {
&self.payload
}

/// Digest function
#[allow(clippy::expect_used)]
pub fn digest_function(&self) -> Algorithm {
Expand Down Expand Up @@ -485,19 +495,33 @@ impl Decode for PublicKey {
}

/// Private Key used in signatures.
#[derive(DebugCustom, Display, Clone, PartialEq, Eq, Getters, Serialize)]
#[getset(get = "pub")]
#[derive(DebugCustom, Display, Clone, PartialEq, Eq, Serialize)]
#[cfg_attr(feature = "ffi", derive(IntoFfi, TryFromFfi))]
#[debug(fmt = "{{ digest: {digest_function}, payload: {:X?}}}", payload)]
#[display(fmt = "{}", "hex::encode(payload)")]
#[allow(clippy::multiple_inherent_impl)]
pub struct PrivateKey {
/// Digest function
#[getset(skip)]
digest_function: ConstString,
/// key payload. WARNING! Do not use `"string".as_bytes()` to obtain the key.
#[serde(with = "hex::serde")]
payload: Vec<u8>,
}

#[cfg_attr(feature = "ffi", ffi_export)]
impl PrivateKey {
/// Key payload
pub fn payload(&self) -> &[u8] {
&self.payload
}

/// Digest function
#[allow(clippy::expect_used)]
pub fn digest_function(&self) -> Algorithm {
self.digest_function.parse().expect("Valid")
}
}

impl PrivateKey {
/// Construct `PrivateKey` from hex encoded string
///
Expand All @@ -523,12 +547,6 @@ impl PrivateKey {
payload: hex::decode(payload)?,
})
}

/// Digest function
#[allow(clippy::expect_used)]
pub fn digest_function(&self) -> Algorithm {
self.digest_function.parse().expect("Valid")
}
}

impl<'de> Deserialize<'de> for PrivateKey {
Expand Down Expand Up @@ -556,6 +574,20 @@ impl<'de> Deserialize<'de> for PrivateKey {
}
}

#[cfg(feature = "ffi")]
mod ffi {
use iroha_ffi::{gen_ffi_impl, handles};

use super::{KeyPair, PrivateKey, PublicKey};

handles! {0, KeyPair, PublicKey, PrivateKey}

gen_ffi_impl! { Clone: KeyPair, PublicKey, PrivateKey}
gen_ffi_impl! { Eq: KeyPair, PublicKey, PrivateKey}
gen_ffi_impl! { Ord: PublicKey }
gen_ffi_impl! { Drop: KeyPair, PublicKey, PrivateKey}
}

/// The prelude re-exports most commonly used traits, structs and macros from this crate.
pub mod prelude {
pub use super::{Algorithm, Hash, KeyPair, PrivateKey, PublicKey, Signature};
Expand Down
9 changes: 4 additions & 5 deletions crypto/src/merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,16 +125,15 @@ impl<T: IntoSchema> IntoSchema for MerkleTree<T> {
format!("{}::MerkleTree<{}>", module_path!(), T::type_name())
}
fn schema(map: &mut MetaMap) {
// NOTE: Leaf nodes in the order of insertion
map.entry(Self::type_name()).or_insert_with(|| {
// BFS ordered list of leaf nodes
Metadata::Vec(VecMeta {
ty: HashOf::<T>::type_name(),
sorted: true,
sorted: false,
})
});
if !map.contains_key(&HashOf::<T>::type_name()) {
HashOf::<T>::schema(map);
}

HashOf::<T>::schema(map);
}
}

Expand Down
6 changes: 3 additions & 3 deletions crypto/src/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl Signature {
#[cfg(feature = "std")]
pub fn verify(&self, payload: &[u8]) -> Result<(), Error> {
let algorithm: Algorithm = self.public_key.digest_function();
let public_key = UrsaPublicKey(self.public_key.payload().clone());
let public_key = UrsaPublicKey(self.public_key.payload().to_owned());

match algorithm {
Algorithm::Ed25519 => Ed25519Sha512::new().verify(payload, self.payload(), &public_key),
Expand Down Expand Up @@ -186,13 +186,13 @@ impl<T: IntoSchema> IntoSchema for SignatureOf<T> {
format!("{}::SignatureOf<{}>", module_path!(), T::type_name())
}
fn schema(map: &mut MetaMap) {
Signature::schema(map);

map.entry(Self::type_name()).or_insert_with(|| {
Metadata::Tuple(UnnamedFieldsMeta {
types: vec![Signature::type_name()],
})
});

Signature::schema(map);
}
}

Expand Down
4 changes: 2 additions & 2 deletions data_model/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ default = ["std"]
# Disabled for WASM interoperability, to reduce the binary size.
# Please refer to https://docs.rust-embedded.org/book/intro/no-std.html
std = ["iroha_macro/std", "iroha_version/std", "iroha_version/warp", "iroha_crypto/std", "iroha_primitives/std", "thiserror", "strum/std", "dashmap", "tokio"]
# Expose FFI API to facilitate dynamic linking
ffi_api = ["iroha_ffi", "iroha_crypto/ffi_api"]
# Generate extern functions callable via FFI
ffi = ["iroha_crypto/ffi", "iroha_ffi"]

# Expose API for mutating structures (Internal use only)
mutable_api = []
Expand Down
24 changes: 14 additions & 10 deletions data_model/src/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use std::collections::{btree_map, btree_set};

use derive_more::Display;
use getset::{Getters, MutGetters, Setters};
#[cfg(feature = "ffi_api")]
use iroha_ffi::ffi_bindgen;
#[cfg(feature = "ffi")]
use iroha_ffi::{ffi_export, IntoFfi, TryFromFfi};
use iroha_schema::IntoSchema;
use parity_scale_codec::{Decode, Encode};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -82,14 +82,15 @@ impl From<GenesisAccount> for Account {
Clone,
PartialEq,
Eq,
PartialOrd,
Ord,
Decode,
Encode,
Deserialize,
Serialize,
IntoSchema,
PartialOrd,
Ord,
)]
#[cfg_attr(feature = "ffi", derive(IntoFfi, TryFromFfi))]
pub struct SignatureCheckCondition(pub EvaluatesTo<bool>);

impl SignatureCheckCondition {
Expand Down Expand Up @@ -128,6 +129,7 @@ impl Default for SignatureCheckCondition {
#[derive(
Debug, Display, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema,
)]
#[cfg_attr(feature = "ffi", derive(IntoFfi, TryFromFfi))]
#[display(fmt = "[{id}]")]
pub struct NewAccount {
/// Identification
Expand Down Expand Up @@ -190,12 +192,12 @@ impl NewAccount {
}

/// Identification
pub fn id(&self) -> &<Account as Identifiable>::Id {
pub(crate) fn id(&self) -> &<Account as Identifiable>::Id {
&self.id
}
}

#[cfg_attr(feature = "ffi_api", ffi_bindgen)]
#[cfg_attr(feature = "ffi", ffi_export)]
impl NewAccount {
/// Add [`Metadata`] to the account replacing previously defined
#[must_use]
Expand All @@ -221,9 +223,9 @@ impl NewAccount {
Serialize,
IntoSchema,
)]
#[allow(clippy::multiple_inherent_impl)]
#[cfg_attr(feature = "ffi_api", ffi_bindgen)]
#[cfg_attr(feature = "ffi", derive(IntoFfi, TryFromFfi))]
#[display(fmt = "({id})")] // TODO: Add more?
#[allow(clippy::multiple_inherent_impl)]
pub struct Account {
/// An Identification of the [`Account`].
id: <Self as Identifiable>::Id,
Expand All @@ -234,7 +236,8 @@ pub struct Account {
/// Permissions tokens of this account
permission_tokens: Permissions,
/// Condition which checks if the account has the right signatures.
#[cfg_attr(feature = "mutable_api", getset(get = "pub", set = "pub"))]
#[getset(get = "pub")]
#[cfg_attr(feature = "mutable_api", getset(set = "pub"))]
signature_check_condition: SignatureCheckCondition,
/// Metadata of this account as a key-value store.
#[cfg_attr(feature = "mutable_api", getset(get_mut = "pub"))]
Expand Down Expand Up @@ -275,7 +278,7 @@ impl Ord for Account {
}
}

#[cfg_attr(feature = "ffi_api", ffi_bindgen)]
#[cfg_attr(feature = "ffi", ffi_export)]
impl Account {
/// Construct builder for [`Account`] identifiable by [`Id`] containing the given signatories.
#[must_use]
Expand Down Expand Up @@ -434,6 +437,7 @@ impl FromIterator<Account> for crate::Value {
Serialize,
IntoSchema,
)]
#[cfg_attr(feature = "ffi", derive(IntoFfi, TryFromFfi))]
#[display(fmt = "{name}@{domain_id}")]
pub struct Id {
/// [`Account`]'s name.
Expand Down
Loading

0 comments on commit 82fa83f

Please sign in to comment.