Skip to content
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
226 changes: 114 additions & 112 deletions Cargo.lock

Large diffs are not rendered by default.

41 changes: 35 additions & 6 deletions dash-spv-apple-bindings/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,18 @@ for target in "x86_64-apple-darwin" "aarch64-apple-darwin" "x86_64-apple-ios" "a
rustup target add "$target"
fi
done

wait
cp -p ferment_injections.rs src/fermented.rs
wait
rm -rf target/{framework,include,lib}
wait
cargo lipo --$BUILD_FLAG
build_targets=(
"x86_64-apple-ios"
"aarch64-apple-ios"
"aarch64-apple-ios-sim"
"x86_64-apple-darwin"
"aarch64-apple-darwin"

)
export IPHONEOS_DEPLOYMENT_TARGET=$MIN_IOS
export MACOSX_DEPLOYMENT_TARGET=$MIN_MACOS
Expand All @@ -77,6 +79,8 @@ else
features=""
fi

mkdir -p target/{framework,include,lib/{ios,ios-simulator,macos}}

fermentize=1
for target in "${build_targets[@]}"; do
echo "▶ Building for $target"
Expand All @@ -89,16 +93,14 @@ for target in "${build_targets[@]}"; do
extra_features=""
fi

if [ ! -f "$lib_path" ]; then
# if [ ! -f "$lib_path" ]; then
cargo +nightly -Z build-std=std,compiler_builtins build \
--features="$features $extra_features" \
--target="$target" \
--"$BUILD_FLAG"
fi
# fi
done

wait
mkdir -p target/{framework,include,lib/{ios,ios-simulator,macos}}
./verify_o_set.sh $MIN_IOS ../target/"$BUILD_TYPE"
./verify_a_lib.sh $MIN_IOS ../target/x86_64-apple-ios/"$BUILD_TYPE"/lib${LIB_NAME}.a
./verify_a_lib.sh $MIN_IOS ../target/aarch64-apple-ios/"$BUILD_TYPE"/lib${LIB_NAME}.a
Expand All @@ -122,6 +124,33 @@ if $OBJC; then
fi
fi

#TODO: there is a bug in cbindgen that can't deal with featured functions arguments
sed -E -i '' '
/dpp_data_contract_document_type_v1_DocumentTypeV1_ctor\(/,/token_costs_TokenCosts \*/ {
/StatelessJsonSchemaLazyValidator \*json_schema_validator/d
}
/dpp_data_contract_document_type_v1_DocumentTypeV1_ctor\(/,/token_costs_TokenCosts \*/ {
/token_costs_TokenCosts \*/i\
#if (!defined(TEST) && defined(DPP_VALIDATION))\
StatelessJsonSchemaLazyValidator *json_schema_validator,\
#endif
}
' target/include/dash_spv_apple_bindings.h

sed -E -i '' '
/dpp_data_contract_document_type_v0_DocumentTypeV0_ctor\(/,/StatelessJsonSchemaLazyValidator \*json_schema_validator\);/ {
s/(\*security_level_requirement),/\1/;
s/StatelessJsonSchemaLazyValidator \*json_schema_validator\);/\
#if (!defined(TEST) \&\& defined(DPP_VALIDATION))\
,\
StatelessJsonSchemaLazyValidator *json_schema_validator\
#endif\
);\
/
}
' target/include/dash_spv_apple_bindings.h


#TODO: ferment should be used instead of sed
sed -i '' '/#ifndef/ a\
typedef struct Runtime Runtime;
Expand Down
2 changes: 1 addition & 1 deletion dash-spv-apple-bindings/src/fermented.rs

Large diffs are not rendered by default.

28 changes: 26 additions & 2 deletions dash-spv-apple-bindings/src/fermented_extended.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::sync::Arc;
use ferment::{boxed, unbox_any};
use ferment::{boxed, destroy_opt_primitive, unbox_any};
use tokio::runtime::Runtime;
use dash_spv_coinjoin::coinjoin_client_manager::CoinJoinClientManager;
use crate::custom::dashcore::{dashcore_hash_types_BlockHash, dashcore_hash_types_ConfirmedHash, dashcore_hash_types_ConfirmedHashHashedWithProRegTx, dashcore_hash_types_CycleHash, dashcore_hash_types_InputsHash, dashcore_hash_types_MerkleRootMasternodeList, dashcore_hash_types_MerkleRootQuorums, dashcore_hash_types_ProTxHash, dashcore_hash_types_PubkeyHash, dashcore_hash_types_QuorumCommitmentHash, dashcore_hash_types_QuorumEntryHash, dashcore_hash_types_QuorumHash, dashcore_hash_types_QuorumSigningRequestId, dashcore_hash_types_QuorumVVecHash, dashcore_hash_types_ScriptHash, dashcore_hash_types_Sha256dHash, dashcore_hash_types_SpecialTransactionPayloadHash, dashcore_hash_types_TxMerkleNode, dashcore_hash_types_Txid};
Expand Down Expand Up @@ -29,12 +29,37 @@ pub unsafe extern "C" fn SocketAddr_destroy(self_: *mut SocketAddr) {
pub unsafe extern "C" fn dash_spv_apple_bindings_DashSPVCore_destroy(self_: *mut DashSPVCore) {
unbox_any(self_);
}
# [no_mangle]
pub unsafe extern "C" fn dash_spv_platform_identity_model_IdentityModel_destroy(self_: *mut dash_spv_platform::identity::model::IdentityModel) {
unbox_any(self_);
}

# [no_mangle]
pub unsafe extern "C" fn dash_spv_coinjoin_coinjoin_client_manager_CoinJoinClientManager_destroy(self_: *mut CoinJoinClientManager) {
unbox_any(self_);
}

#[no_mangle]
pub unsafe extern "C" fn u64_destroy(self_: *mut u64) { destroy_opt_primitive(self_); }
#[no_mangle]
pub unsafe extern "C" fn i64_destroy(self_: *mut i64) { destroy_opt_primitive(self_); }
#[no_mangle]
pub unsafe extern "C" fn u32_destroy(self_: *mut u32) { destroy_opt_primitive(self_); }
#[no_mangle]
pub unsafe extern "C" fn i32_destroy(self_: *mut i32) { destroy_opt_primitive(self_); }
#[no_mangle]
pub unsafe extern "C" fn u16_destroy(self_: *mut u16) { destroy_opt_primitive(self_); }
#[no_mangle]
pub unsafe extern "C" fn i16_destroy(self_: *mut i16) { destroy_opt_primitive(self_); }
#[no_mangle]
pub unsafe extern "C" fn u8_destroy(self_: *mut u8) { destroy_opt_primitive(self_); }
#[no_mangle]
pub unsafe extern "C" fn i8_destroy(self_: *mut i8) { destroy_opt_primitive(self_); }
#[no_mangle]
pub unsafe extern "C" fn usize_destroy(self_: *mut usize) { destroy_opt_primitive(self_); }
#[no_mangle]
pub unsafe extern "C" fn isize_destroy(self_: *mut isize) { destroy_opt_primitive(self_); }

/// [u8; 32]
#[no_mangle] pub unsafe extern "C" fn dashcore_hash_types_BlockHash_ctor(hash: *mut Arr_u8_32) -> *mut dashcore_hash_types_BlockHash {
to_ffi_hash::<dashcore::hash_types::BlockHash, _, _>(hash)
Expand Down Expand Up @@ -208,4 +233,3 @@ pub unsafe extern "C" fn dash_spv_coinjoin_coinjoin_client_manager_CoinJoinClien
#[no_mangle] pub unsafe extern "C" fn dashcore_hash_types_ScriptHash_inner(ptr: *mut dashcore_hash_types_ScriptHash) -> *mut Arr_u8_20 {
to_ffi_bytes::<dashcore::hash_types::ScriptHash, _, _>(ptr)
}

39 changes: 21 additions & 18 deletions dash-spv-apple-bindings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ pub extern crate dash_spv_masternode_processor;
pub extern crate dash_spv_coinjoin;

use std::fmt::{Debug, Formatter};
use std::os::raw::c_void;
use std::sync::Arc;
use dashcore::{Network, QuorumHash};
use dashcore::hashes::Hash;
use dashcore::sml::llmq_type::LLMQType;
use dashcore::sml::masternode_list_entry::qualified_masternode_list_entry::QualifiedMasternodeListEntry;
use data_contracts::SystemDataContract;
use dpp::data_contract::DataContract;
use dpp::identity::identity_public_key::IdentityPublicKey;

Expand All @@ -41,45 +43,45 @@ use crate::ffi_core_provider::FFICoreProvider;
pub struct DashSPVCore {
pub processor: Arc<MasternodeProcessor>,
pub platform: Arc<PlatformSDK>,
context: *const std::os::raw::c_void,
context: *const c_void,
}

impl Debug for DashSPVCore {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(format!("[{}] [SPVCore]", self.processor.provider.chain_type().name()).as_str())
}
}
// AnyOther by_value: Type(Dictionary(NonPrimitiveFermentable(SmartPointer(Arc($Ty(std :: sync :: Arc < dyn Fn (* const std :: os :: raw :: c_void , u32) -> Option < [u8 ; 32] > >, [Object(Type(Dictionary(LambdaFn($Ty(dyn Fn (* const std :: os :: raw :: c_void , u32) -> Option < [u8 ; 32] >, [])))))]))))))


#[ferment_macro::export]
impl DashSPVCore {

pub fn with_callbacks<
// platform
DC: Fn(*const std::os::raw::c_void, Identifier) -> Result<Option<Arc<DataContract>>, ContextProviderError> + Send + Sync + 'static,
AH: Fn(*const std::os::raw::c_void) -> Result<CoreBlockHeight, ContextProviderError> + Send + Sync + 'static,
CS: Fn(*const std::os::raw::c_void, &IdentityPublicKey, Vec<u8>) -> Result<BinaryData, ProtocolError> + Send + Sync + 'static,
CCS: Fn(*const std::os::raw::c_void, &IdentityPublicKey) -> bool + Send + Sync + 'static,
GetDataContract: Fn(*const c_void, Identifier) -> Result<Option<Arc<DataContract>>, ContextProviderError> + Send + Sync + 'static,
GetPlatformActivationHeight: Fn(*const c_void) -> Result<CoreBlockHeight, ContextProviderError> + Send + Sync + 'static,
Sign: Fn(*const c_void, &IdentityPublicKey, Vec<u8>) -> Result<BinaryData, ProtocolError> + Send + Sync + 'static,
CanSign: Fn(*const c_void, &IdentityPublicKey) -> bool + Send + Sync + 'static,
GetDataContractFromCache: Fn(*const c_void, SystemDataContract) -> DataContract + Send + Sync + 'static,
// masternode
BHT: Fn(*const std::os::raw::c_void, [u8; 32]) -> u32 + Send + Sync + 'static,
BHH: Fn(*const std::os::raw::c_void, u32) -> Option<[u8; 32]> + Send + Sync + 'static,
UMU: Fn(*const std::os::raw::c_void, Vec<QualifiedMasternodeListEntry>) + Send + Sync + 'static,
GetBlockHeightByBlockHash: Fn(*const c_void, [u8; 32]) -> u32 + Send + Sync + 'static,
GetBlockHashByBlockHeight: Fn(*const c_void, u32) -> Option<[u8; 32]> + Send + Sync + 'static,
UpdateMasternodesAddressUsage: Fn(*const c_void, Vec<QualifiedMasternodeListEntry>) + Send + Sync + 'static,
>(
chain_type: ChainType,
diff_config: Option<DiffConfig>,
address_list: Option<Vec<&'static str>>,

get_data_contract: DC,
get_platform_activation_height: AH,
callback_signer: CS,
callback_can_sign: CCS,
get_data_contract: GetDataContract,
get_platform_activation_height: GetPlatformActivationHeight,
callback_signer: Sign,
callback_can_sign: CanSign,
get_data_contract_from_cache: GetDataContractFromCache,

get_block_height_by_hash: BHT,
get_block_hash_by_height: BHH,
update_address_usage_of_masternodes: UMU,
get_block_height_by_hash: GetBlockHeightByBlockHash,
get_block_hash_by_height: GetBlockHashByBlockHeight,
update_address_usage_of_masternodes: UpdateMasternodesAddressUsage,

context: *const std::os::raw::c_void) -> Self {
context: *const c_void) -> Self {
let provider = Arc::new(FFICoreProvider::new(
chain_type.clone(),
get_block_height_by_hash,
Expand All @@ -104,6 +106,7 @@ impl DashSPVCore {
get_platform_activation_height,
callback_signer,
callback_can_sign,
get_data_contract_from_cache,
address_list,
chain_type,
context
Expand Down
2 changes: 1 addition & 1 deletion dash-spv-crypto/src/keys/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::util::data_append::DataAppend;
use crate::util::script::ScriptElement;
use crate::util::sec_vec::SecVec;

#[derive(Clone, Debug, PartialEq)]
#[derive(Copy, Clone, Debug, PartialEq)]
#[ferment_macro::export]
pub enum KeyKind {
ECDSA = 0,
Expand Down
1 change: 0 additions & 1 deletion dash-spv-masternode-processor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ std = ["dashcore/std"]
bincode = "=2.0.0-rc.3"
dash-spv-crypto = { workspace = true }
dashcore = { git = "https://github.com/dashpay/rust-dashcore", features = ["std", "secp-recovery", "rand", "signer", "serde", "apple", "bincode", "ed25519-dalek"], default-features = false, branch = "feat/ferment" }
ferment = { version = "0.2", package = "ferment" }
ferment-macro = { version = "0.2", package = "ferment-macro" }
serde = { version = "1.0.215", features = ["derive"], optional = true }
serde_json = "1.0.85"
Expand Down
1 change: 1 addition & 0 deletions dash-spv-platform/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ ferment-macro = { version = "0.2", package = "ferment-macro" }
http = { version = "1.3.1" }
indexmap = "2.9.0"
tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread"] }
log = "0.4.27"

[features]
default = ["state-transitions"]
Expand Down
17 changes: 17 additions & 0 deletions dash-spv-platform/src/contract/model.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use std::os::raw::c_void;
use std::sync::Arc;
use dpp::data_contract::DataContract;

#[ferment_macro::export]
pub enum ContractState {
Unknown,
NotRegistered,
Registered,
Registering,
}
#[ferment_macro::opaque]
pub struct ContractModel {
pub contract: DataContract,
pub state: ContractState,
pub save: Arc<dyn Fn(*const c_void) -> bool>,
}
72 changes: 68 additions & 4 deletions dash-spv-platform/src/document/contact_request.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::os::raw::c_void;
use std::sync::Arc;
use dapi_grpc::platform::v0::get_documents_request::get_documents_request_v0::Start;
use dash_sdk::platform::DocumentQuery;
use dash_sdk::Sdk;
use dash_sdk::platform::{DocumentQuery, FetchMany};
use dash_sdk::{RequestSettings, Sdk};
use dash_spv_macro::StreamManager;
use dpp::data_contract::DataContract;
use dpp::data_contracts::SystemDataContract;
Expand All @@ -12,11 +13,19 @@ use drive_proof_verifier::types::RetrievedObjects;
use indexmap::IndexMap;
use platform_value::Identifier;
use crate::error::Error;
use crate::identity::model::IdentityModel;
use crate::models::contact_request::{ContactRequest, ContactRequestKind};
use crate::query::{order_by_asc_created_at, where_created_since, where_owner_is, where_recipient_is};
use crate::util::{RetryStrategy, StreamManager, StreamSettings, StreamSpec, Validator};

#[derive(Clone)]
pub const CONTACT_REQUEST_SETTINGS: RequestSettings = RequestSettings {
connect_timeout: None,
timeout: None,
retries: Some(5),
ban_failed_address: None,
};

#[derive(Clone, Debug)]
#[ferment_macro::export]
pub enum ContactRequestValidator {
None = 0,
Expand Down Expand Up @@ -48,11 +57,12 @@ impl StreamSpec for ContactRequestValidator {
type ResultMany = IndexMap<Identifier, Option<Document>>;
}

#[derive(Clone, Debug, StreamManager)]
#[derive(Clone, StreamManager)]
#[ferment_macro::opaque]
pub struct ContactRequestManager {
pub sdk: Arc<Sdk>,
pub chain_type: ChainType,
// pub has_contact_request_with_id: Arc<dyn Fn(/*context*/*const c_void, /*direction*/ bool, /*identifier*/[u8; 32], /*storage_context*/*const c_void) -> bool>,
}

impl ContactRequestManager {
Expand Down Expand Up @@ -137,6 +147,60 @@ impl ContactRequestManager {
self.stream_many_with_settings::<ContactRequestValidator, Document, DocumentQuery>(query, retry, StreamSettings::default_with_delay(delay), options).await
.map(|docs| process_contact_requests(&user_id, docs))
}

pub async fn fetch_incoming_contact_requests_in_context<
HasContactRequestWithId: Fn(/*context*/*const c_void, /*direction*/ bool, /*identifier*/[u8; 32], /*storage_context*/*const c_void) -> bool + Send + Sync + 'static
>(
&self,
model: &mut IdentityModel,
contract: DataContract,
since: u64,
start_after: Option<Vec<u8>>,
storage_context: *const c_void,
context: *const c_void,
has_contact_request_with_id: HasContactRequestWithId,
) ->Result<Vec<ContactRequest>, Error> {
let user_id = model.unique_id;
let query = self.query_incoming_contact_requests(contract, user_id, since, start_after)?;
let (documents, _metadata) = Document::fetch_many_with_metadata(self.sdk_ref(), query, Some(CONTACT_REQUEST_SETTINGS)).await?;
let mut contact_requests = Vec::new();
for (_, document) in documents {
if let Some(doc) = document {
let request = ContactRequest::try_from(doc)?;
if user_id.eq(&request.recipient) && !has_contact_request_with_id(context, true, request.owner_id, storage_context) {
contact_requests.push(request);
}
}
}
Ok(contact_requests)
}
pub async fn fetch_outgoing_contact_requests_in_context<
HasContactRequestWithId: Fn(/*context*/*const c_void, /*direction*/ bool, /*identifier*/[u8; 32], /*storage_context*/*const c_void) -> bool + Send + Sync + 'static
>(
&self,
model: &mut IdentityModel,
contract: DataContract,
since: u64,
start_after: Option<Vec<u8>>,
storage_context: *const c_void,
context: *const c_void,
has_contact_request_with_id: HasContactRequestWithId,
) -> Result<Vec<ContactRequest>, Error> {
let user_id = model.unique_id;
let query = self.query_outgoing_contact_requests(contract, user_id, since, start_after)?;
let (documents, _metadata) = Document::fetch_many_with_metadata(self.sdk_ref(), query, Some(CONTACT_REQUEST_SETTINGS)).await?;
let mut contact_requests = Vec::new();
for (_, document) in documents {
if let Some(doc) = document {
let request = ContactRequest::try_from(doc)?;
let recipient = request.recipient;
if !user_id.eq(&recipient) && !has_contact_request_with_id(context, false, recipient, storage_context) {
contact_requests.push(request);
}
}
}
Ok(contact_requests)
}
}

fn process_contact_requests(user_id: &[u8; 32], documents: Documents) -> Vec<ContactRequestKind> {
Expand Down
Loading
Loading