Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] #2434: FFI bindgen library #2314

Merged
merged 15 commits into from
Jul 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,
mversic marked this conversation as resolved.
Show resolved Hide resolved
})
});
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"]
mversic marked this conversation as resolved.
Show resolved Hide resolved

# 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