Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 4 additions & 0 deletions Cargo.lock

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

41 changes: 35 additions & 6 deletions packages/rs-dash-platform-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,51 @@ pub fn stack_size(attr: TokenStream, item: TokenStream) -> TokenStream {

let attrs = function.attrs;
let vis = function.vis;
let sig = function.sig;
let mut sig = function.sig;
let block = function.block;
let fn_ident = sig.ident.clone();

// If the function is async, we strip async from the outer signature
// and run the body on a new tokio current-thread runtime inside the
// spawned thread. This keeps the externally-visible function sync so
// that it works with `#[test]` (and avoids needing `#[tokio::test]`).
let is_async = sig.asyncness.is_some();
if is_async {
sig.asyncness = None;
}

let spawned_body = if is_async {
quote! {
builder
.spawn(move || {
::tokio::runtime::Builder::new_current_thread()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can deadlock, workaround in #3490

.enable_all()
.build()
.expect("failed to build tokio runtime for stack_size thread")
.block_on(async move #block)
})
.expect("failed to spawn stack_size thread")
.join()
.expect("stack_size thread panicked")
}
} else {
quote! {
builder
.spawn(move || #block)
.expect("failed to spawn stack_size thread")
.join()
.expect("stack_size thread panicked")
}
};

TokenStream::from(quote! {
#(#attrs)*
#vis #sig {
let builder = ::std::thread::Builder::new()
.stack_size(#stack_size_expr)
.name(::std::string::String::from(stringify!(#fn_ident)));

builder
.spawn(|| #block)
.expect("failed to spawn stack_size thread")
.join()
.expect("stack_size thread panicked")
#spawned_body
}
})
}
Expand Down
28 changes: 20 additions & 8 deletions packages/rs-dpp/src/identity/signer.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,42 @@
use crate::address_funds::AddressWitness;
use crate::ProtocolError;
use async_trait::async_trait;
use platform_value::BinaryData;
use std::fmt::Debug;
use std::sync::Arc;

pub trait Signer<K>: Sync + Debug {
#[async_trait]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure we still want to use async_trtait vs ? Why in lib.rs we have #![allow(async_fn_in_trait)]?

pub trait Signer<K>: Send + Sync + Debug {
/// the public key bytes are only used to look up the private key
fn sign(&self, key: &K, data: &[u8]) -> Result<BinaryData, ProtocolError>;
async fn sign(&self, key: &K, data: &[u8]) -> Result<BinaryData, ProtocolError>;

/// the public key bytes are only used to look up the private key
fn sign_create_witness(&self, key: &K, data: &[u8]) -> Result<AddressWitness, ProtocolError>;
async fn sign_create_witness(
&self,
key: &K,
data: &[u8],
) -> Result<AddressWitness, ProtocolError>;

/// do we have this identity public key in the signer?
fn can_sign_with(&self, key: &K) -> bool;
}

#[async_trait]
impl<K, S> Signer<K> for Arc<S>
where
S: Signer<K> + ?Sized + Send,
K: Send + Sync,
S: Signer<K> + ?Sized + Send + Sync,
{
fn sign(&self, key: &K, data: &[u8]) -> Result<BinaryData, ProtocolError> {
(**self).sign(key, data)
async fn sign(&self, key: &K, data: &[u8]) -> Result<BinaryData, ProtocolError> {
(**self).sign(key, data).await
}

fn sign_create_witness(&self, key: &K, data: &[u8]) -> Result<AddressWitness, ProtocolError> {
(**self).sign_create_witness(key, data)
async fn sign_create_witness(
&self,
key: &K,
data: &[u8],
) -> Result<AddressWitness, ProtocolError> {
(**self).sign_create_witness(key, data).await
}

fn can_sign_with(&self, key: &K) -> bool {
Expand Down
1 change: 1 addition & 0 deletions packages/rs-dpp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//#![deny(missing_docs)]
#![allow(dead_code)]
#![allow(clippy::result_large_err)]
#![allow(async_fn_in_trait)]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use legacy async_trtait everywhere, not sure if #![allow(async_fn_in_trait)] is intentional.


extern crate core;

Expand Down
26 changes: 17 additions & 9 deletions packages/rs-dpp/src/shielded/builder/shield.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use super::{build_output_only_bundle, serialize_authorized_bundle, OrchardProver
/// - `memo` - 36-byte structured memo for the recipient (4-byte type tag + 32-byte payload)
/// - `platform_version` - Protocol version
#[allow(clippy::too_many_arguments)]
pub fn build_shield_transition<S: Signer<PlatformAddress>, P: OrchardProver>(
pub async fn build_shield_transition<S: Signer<PlatformAddress>, P: OrchardProver>(
recipient: &OrchardAddress,
shield_amount: u64,
inputs: BTreeMap<PlatformAddress, (AddressNonce, Credits)>,
Expand Down Expand Up @@ -61,6 +61,7 @@ pub fn build_shield_transition<S: Signer<PlatformAddress>, P: OrchardProver>(
user_fee_increase,
platform_version,
)
.await
}

#[cfg(test)]
Expand All @@ -76,12 +77,17 @@ mod tests {
#[derive(Debug)]
struct DummySigner;

#[async_trait::async_trait]
impl Signer<PlatformAddress> for DummySigner {
fn sign(&self, _key: &PlatformAddress, _data: &[u8]) -> Result<BinaryData, ProtocolError> {
async fn sign(
&self,
_key: &PlatformAddress,
_data: &[u8],
) -> Result<BinaryData, ProtocolError> {
Ok(BinaryData::new(vec![0u8; 65]))
}

fn sign_create_witness(
async fn sign_create_witness(
&self,
_key: &PlatformAddress,
_data: &[u8],
Expand All @@ -96,8 +102,8 @@ mod tests {
}
}

#[test]
fn test_build_shield_empty_fee_strategy() {
#[tokio::test]
async fn test_build_shield_empty_fee_strategy() {
let recipient = test_orchard_address();
let platform_version = PlatformVersion::latest();
let result = build_shield_transition(
Expand All @@ -110,7 +116,8 @@ mod tests {
&TestProver,
[0u8; 36],
platform_version,
);
)
.await;

assert!(result.is_err());
let err = result.unwrap_err().to_string();
Expand All @@ -121,8 +128,8 @@ mod tests {
);
}

#[test]
fn test_build_shield_transition_valid() {
#[tokio::test]
async fn test_build_shield_transition_valid() {
let recipient = test_orchard_address();
let platform_version = PlatformVersion::latest();
// Create a P2PKH address as input
Expand All @@ -142,7 +149,8 @@ mod tests {
&TestProver,
[0u8; 36],
platform_version,
);
)
.await;

assert!(result.is_ok(), "expected Ok, got: {:?}", result.err());
match result.unwrap() {
Expand Down
7 changes: 4 additions & 3 deletions packages/rs-dpp/src/state_transition/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -940,7 +940,7 @@ impl StateTransition {
}

#[cfg(feature = "state-transition-signing")]
pub fn sign_external<S: Signer<IdentityPublicKey>>(
pub async fn sign_external<S: Signer<IdentityPublicKey>>(
&mut self,
identity_public_key: &IdentityPublicKey,
signer: &S,
Expand All @@ -954,10 +954,11 @@ impl StateTransition {
get_data_contract_security_level_requirement,
StateTransitionSigningOptions::default(),
)
.await
}

#[cfg(feature = "state-transition-signing")]
pub fn sign_external_with_options<S: Signer<IdentityPublicKey>>(
pub async fn sign_external_with_options<S: Signer<IdentityPublicKey>>(
&mut self,
identity_public_key: &IdentityPublicKey,
signer: &S,
Expand Down Expand Up @@ -1107,7 +1108,7 @@ impl StateTransition {
}
}
let data = self.signable_bytes()?;
self.set_signature(signer.sign(identity_public_key, data.as_slice())?);
self.set_signature(signer.sign(identity_public_key, data.as_slice()).await?);
self.set_signature_public_key_id(identity_public_key.id());
Ok(())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use platform_version::version::PlatformVersion;

impl AddressCreditWithdrawalTransitionMethodsV0 for AddressCreditWithdrawalTransition {
#[cfg(feature = "state-transition-signing")]
fn try_from_inputs_with_signer<S: Signer<PlatformAddress>>(
async fn try_from_inputs_with_signer<S: Signer<PlatformAddress>>(
inputs: BTreeMap<PlatformAddress, (AddressNonce, Credits)>,
output: Option<(PlatformAddress, Credits)>,
fee_strategy: AddressFundsFeeStrategy,
Expand Down Expand Up @@ -57,7 +57,8 @@ impl AddressCreditWithdrawalTransitionMethodsV0 for AddressCreditWithdrawalTrans
signer,
user_fee_increase,
platform_version,
)?,
)
.await?,
),
version => Err(ProtocolError::UnknownVersionMismatch {
method: "AddressCreditWithdrawalTransition::try_from_inputs_with_signer"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use platform_version::version::PlatformVersion;
pub trait AddressCreditWithdrawalTransitionMethodsV0 {
#[cfg(feature = "state-transition-signing")]
#[allow(clippy::too_many_arguments)]
fn try_from_inputs_with_signer<S: Signer<PlatformAddress>>(
async fn try_from_inputs_with_signer<S: Signer<PlatformAddress>>(
inputs: BTreeMap<PlatformAddress, (AddressNonce, Credits)>,
output: Option<(PlatformAddress, Credits)>,
fee_strategy: AddressFundsFeeStrategy,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use platform_version::version::PlatformVersion;

impl AddressCreditWithdrawalTransitionMethodsV0 for AddressCreditWithdrawalTransitionV0 {
#[cfg(feature = "state-transition-signing")]
fn try_from_inputs_with_signer<S: Signer<PlatformAddress>>(
async fn try_from_inputs_with_signer<S: Signer<PlatformAddress>>(
inputs: BTreeMap<PlatformAddress, (AddressNonce, Credits)>,
output: Option<(PlatformAddress, Credits)>,
fee_strategy: AddressFundsFeeStrategy,
Expand Down Expand Up @@ -61,10 +61,11 @@ impl AddressCreditWithdrawalTransitionMethodsV0 for AddressCreditWithdrawalTrans

let signable_bytes = state_transition.signable_bytes()?;

address_credit_withdrawal_transition.input_witnesses = inputs
.keys()
.map(|address| signer.sign_create_witness(address, &signable_bytes))
.collect::<Result<Vec<AddressWitness>, ProtocolError>>()?;
let mut input_witnesses: Vec<AddressWitness> = Vec::with_capacity(inputs.len());
for address in inputs.keys() {
input_witnesses.push(signer.sign_create_witness(address, &signable_bytes).await?);
}
address_credit_withdrawal_transition.input_witnesses = input_witnesses;

tracing::debug!("try_from_inputs_with_signer: Successfully created transition");
Ok(address_credit_withdrawal_transition.into())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use platform_version::version::PlatformVersion;

impl AddressFundingFromAssetLockTransitionMethodsV0 for AddressFundingFromAssetLockTransition {
#[cfg(feature = "state-transition-signing")]
fn try_from_asset_lock_with_signer<S: Signer<PlatformAddress>>(
async fn try_from_asset_lock_with_signer<S: Signer<PlatformAddress>>(
asset_lock_proof: AssetLockProof,
asset_lock_proof_private_key: &[u8],
inputs: BTreeMap<PlatformAddress, (AddressNonce, Credits)>,
Expand All @@ -52,7 +52,8 @@ impl AddressFundingFromAssetLockTransitionMethodsV0 for AddressFundingFromAssetL
signer,
user_fee_increase,
platform_version,
)?,
)
.await?,
),
version => Err(ProtocolError::UnknownVersionMismatch {
method: "AddressFundingFromAssetLockTransition::try_from_asset_lock_with_signer"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use platform_version::version::PlatformVersion;
pub trait AddressFundingFromAssetLockTransitionMethodsV0 {
#[cfg(feature = "state-transition-signing")]
#[allow(clippy::too_many_arguments)]
fn try_from_asset_lock_with_signer<S: Signer<PlatformAddress>>(
async fn try_from_asset_lock_with_signer<S: Signer<PlatformAddress>>(
asset_lock_proof: AssetLockProof,
asset_lock_proof_private_key: &[u8],
inputs: BTreeMap<PlatformAddress, (AddressNonce, Credits)>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use platform_version::version::PlatformVersion;

impl AddressFundingFromAssetLockTransitionMethodsV0 for AddressFundingFromAssetLockTransitionV0 {
#[cfg(feature = "state-transition-signing")]
fn try_from_asset_lock_with_signer<S: Signer<PlatformAddress>>(
async fn try_from_asset_lock_with_signer<S: Signer<PlatformAddress>>(
asset_lock_proof: AssetLockProof,
asset_lock_proof_private_key: &[u8],
inputs: BTreeMap<PlatformAddress, (AddressNonce, Credits)>,
Expand Down Expand Up @@ -59,10 +59,11 @@ impl AddressFundingFromAssetLockTransitionMethodsV0 for AddressFundingFromAssetL
address_funding_transition.signature = signature.to_vec().into();

// Sign with input witnesses
address_funding_transition.input_witnesses = inputs
.keys()
.map(|address| signer.sign_create_witness(address, &signable_bytes))
.collect::<Result<Vec<AddressWitness>, ProtocolError>>()?;
let mut input_witnesses: Vec<AddressWitness> = Vec::with_capacity(inputs.len());
for address in inputs.keys() {
input_witnesses.push(signer.sign_create_witness(address, &signable_bytes).await?);
}
address_funding_transition.input_witnesses = input_witnesses;

tracing::debug!("try_from_asset_lock_with_signer: Successfully created transition");
Ok(address_funding_transition.into())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use platform_version::version::PlatformVersion;

impl AddressFundsTransferTransitionMethodsV0 for AddressFundsTransferTransition {
#[cfg(feature = "state-transition-signing")]
fn try_from_inputs_with_signer<S: Signer<PlatformAddress>>(
async fn try_from_inputs_with_signer<S: Signer<PlatformAddress>>(
inputs: BTreeMap<PlatformAddress, (AddressNonce, Credits)>,
outputs: BTreeMap<PlatformAddress, Credits>,
fee_strategy: AddressFundsFeeStrategy,
Expand All @@ -45,7 +45,8 @@ impl AddressFundsTransferTransitionMethodsV0 for AddressFundsTransferTransition
signer,
user_fee_increase,
platform_version,
)?,
)
.await?,
),
version => Err(ProtocolError::UnknownVersionMismatch {
method: "AddressFundsTransferTransition::try_from_inputs_with_signer".to_string(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use platform_version::version::PlatformVersion;

pub trait AddressFundsTransferTransitionMethodsV0 {
#[cfg(feature = "state-transition-signing")]
fn try_from_inputs_with_signer<S: Signer<PlatformAddress>>(
async fn try_from_inputs_with_signer<S: Signer<PlatformAddress>>(
inputs: BTreeMap<PlatformAddress, (AddressNonce, Credits)>,
outputs: BTreeMap<PlatformAddress, Credits>,
fee_strategy: AddressFundsFeeStrategy,
Expand Down
Loading
Loading