mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-20 22:05:42 +00:00
Refactor: extract functions and types for creating extrinsics (#138)
* Extract extrinsic * Extract extrinsic types to own module * Fix compiler errors * Fix warnings * Fmt * Pin wabt-sys to 0.7.1, it fails (on my machine) with 0.7.2 * Fix up tests * Fmt * Reexport RuntimeVersion
This commit is contained in:
@@ -47,6 +47,7 @@ substrate-subxt-proc-macro = { version = "0.9.0", path = "proc-macro" }
|
|||||||
async-std = { version = "=1.5.0", features = ["attributes"] }
|
async-std = { version = "=1.5.0", features = ["attributes"] }
|
||||||
env_logger = "0.7.1"
|
env_logger = "0.7.1"
|
||||||
wabt = "0.9.2"
|
wabt = "0.9.2"
|
||||||
|
wabt-sys = "=0.7.1" # pinned because 0.7.2 fails to compile
|
||||||
frame-system = { version = "2.0.0-rc4", package = "frame-system" }
|
frame-system = { version = "2.0.0-rc4", package = "frame-system" }
|
||||||
pallet-balances = { version = "2.0.0-rc4", package = "pallet-balances" }
|
pallet-balances = { version = "2.0.0-rc4", package = "pallet-balances" }
|
||||||
sp-keyring = { version = "2.0.0-rc4", package = "sp-keyring" }
|
sp-keyring = { version = "2.0.0-rc4", package = "sp-keyring" }
|
||||||
|
|||||||
@@ -28,11 +28,17 @@ use sp_runtime::{
|
|||||||
transaction_validity::TransactionValidityError,
|
transaction_validity::TransactionValidityError,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::frame::{
|
use crate::{
|
||||||
balances::Balances,
|
frame::{
|
||||||
system::System,
|
balances::Balances,
|
||||||
|
system::System,
|
||||||
|
},
|
||||||
|
runtimes::Runtime,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Extra type.
|
||||||
|
pub type Extra<T> = <<T as Runtime>::Extra as SignedExtra<T>>::Extra;
|
||||||
|
|
||||||
/// SignedExtra checks copied from substrate, in order to remove requirement to implement
|
/// SignedExtra checks copied from substrate, in order to remove requirement to implement
|
||||||
/// substrate's `frame_system::Trait`
|
/// substrate's `frame_system::Trait`
|
||||||
|
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
// Copyright 2019-2020 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of substrate-subxt.
|
||||||
|
//
|
||||||
|
// subxt is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// subxt is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with substrate-subxt. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Create signed or unsigned extrinsics.
|
||||||
|
|
||||||
|
mod extra;
|
||||||
|
mod signer;
|
||||||
|
|
||||||
|
pub use self::{
|
||||||
|
extra::{
|
||||||
|
DefaultExtra,
|
||||||
|
Extra,
|
||||||
|
SignedExtra,
|
||||||
|
},
|
||||||
|
signer::{
|
||||||
|
PairSigner,
|
||||||
|
Signer,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
use sp_runtime::traits::SignedExtension;
|
||||||
|
use sp_version::RuntimeVersion;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
frame::system::System,
|
||||||
|
runtimes::Runtime,
|
||||||
|
Encoded,
|
||||||
|
Error,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// UncheckedExtrinsic type.
|
||||||
|
pub type UncheckedExtrinsic<T> = sp_runtime::generic::UncheckedExtrinsic<
|
||||||
|
<T as System>::Address,
|
||||||
|
Encoded,
|
||||||
|
<T as Runtime>::Signature,
|
||||||
|
Extra<T>,
|
||||||
|
>;
|
||||||
|
|
||||||
|
/// SignedPayload type.
|
||||||
|
pub type SignedPayload<T> = sp_runtime::generic::SignedPayload<Encoded, Extra<T>>;
|
||||||
|
|
||||||
|
/// Creates a signed extrinsic
|
||||||
|
pub async fn create_signed<T>(
|
||||||
|
runtime_version: &RuntimeVersion,
|
||||||
|
genesis_hash: T::Hash,
|
||||||
|
nonce: T::Index,
|
||||||
|
call: Encoded,
|
||||||
|
signer: &(dyn Signer<T> + Send + Sync),
|
||||||
|
) -> Result<UncheckedExtrinsic<T>, Error>
|
||||||
|
where
|
||||||
|
T: Runtime,
|
||||||
|
<<T::Extra as SignedExtra<T>>::Extra as SignedExtension>::AdditionalSigned:
|
||||||
|
Send + Sync,
|
||||||
|
{
|
||||||
|
let spec_version = runtime_version.spec_version;
|
||||||
|
let tx_version = runtime_version.transaction_version;
|
||||||
|
let extra: T::Extra = T::Extra::new(spec_version, tx_version, nonce, genesis_hash);
|
||||||
|
let payload = SignedPayload::<T>::new(call, extra.extra())?;
|
||||||
|
let signed = signer.sign(payload).await?;
|
||||||
|
Ok(signed)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates an unsigned extrinsic
|
||||||
|
pub fn create_unsigned<T>(call: Encoded) -> UncheckedExtrinsic<T>
|
||||||
|
where
|
||||||
|
T: Runtime,
|
||||||
|
{
|
||||||
|
UncheckedExtrinsic::<T>::new_unsigned(call)
|
||||||
|
}
|
||||||
@@ -17,14 +17,12 @@
|
|||||||
//! A library to **sub**mit e**xt**rinsics to a
|
//! A library to **sub**mit e**xt**rinsics to a
|
||||||
//! [substrate](https://github.com/paritytech/substrate) node via RPC.
|
//! [substrate](https://github.com/paritytech/substrate) node via RPC.
|
||||||
|
|
||||||
use crate::{
|
use super::{
|
||||||
extra::SignedExtra,
|
SignedExtra,
|
||||||
runtimes::{
|
SignedPayload,
|
||||||
Runtime,
|
UncheckedExtrinsic,
|
||||||
SignedPayload,
|
|
||||||
UncheckedExtrinsic,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
use crate::runtimes::Runtime;
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use sp_core::Pair;
|
use sp_core::Pair;
|
||||||
use sp_runtime::traits::{
|
use sp_runtime::traits::{
|
||||||
@@ -115,7 +115,7 @@ mod tests {
|
|||||||
RuntimeError,
|
RuntimeError,
|
||||||
},
|
},
|
||||||
events::EventsDecoder,
|
events::EventsDecoder,
|
||||||
signer::{
|
extrinsic::{
|
||||||
PairSigner,
|
PairSigner,
|
||||||
Signer,
|
Signer,
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
@@ -44,8 +44,8 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
error::Error,
|
error::Error,
|
||||||
|
extrinsic::PairSigner,
|
||||||
frame::balances::TransferCall,
|
frame::balances::TransferCall,
|
||||||
signer::PairSigner,
|
|
||||||
tests::{
|
tests::{
|
||||||
test_client,
|
test_client,
|
||||||
TestRuntime,
|
TestRuntime,
|
||||||
|
|||||||
+30
-104
@@ -60,17 +60,16 @@ use sp_core::{
|
|||||||
Bytes,
|
Bytes,
|
||||||
};
|
};
|
||||||
pub use sp_runtime::traits::SignedExtension;
|
pub use sp_runtime::traits::SignedExtension;
|
||||||
use sp_version::RuntimeVersion;
|
pub use sp_version::RuntimeVersion;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
mod events;
|
mod events;
|
||||||
mod extra;
|
pub mod extrinsic;
|
||||||
mod frame;
|
mod frame;
|
||||||
mod metadata;
|
mod metadata;
|
||||||
mod rpc;
|
mod rpc;
|
||||||
mod runtimes;
|
mod runtimes;
|
||||||
mod signer;
|
|
||||||
mod subscription;
|
mod subscription;
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
@@ -79,7 +78,12 @@ pub use crate::{
|
|||||||
EventsDecoder,
|
EventsDecoder,
|
||||||
RawEvent,
|
RawEvent,
|
||||||
},
|
},
|
||||||
extra::*,
|
extrinsic::{
|
||||||
|
PairSigner,
|
||||||
|
SignedExtra,
|
||||||
|
Signer,
|
||||||
|
UncheckedExtrinsic,
|
||||||
|
},
|
||||||
frame::*,
|
frame::*,
|
||||||
metadata::{
|
metadata::{
|
||||||
Metadata,
|
Metadata,
|
||||||
@@ -90,7 +94,6 @@ pub use crate::{
|
|||||||
ExtrinsicSuccess,
|
ExtrinsicSuccess,
|
||||||
},
|
},
|
||||||
runtimes::*,
|
runtimes::*,
|
||||||
signer::*,
|
|
||||||
subscription::*,
|
subscription::*,
|
||||||
substrate_subxt_proc_macro::*,
|
substrate_subxt_proc_macro::*,
|
||||||
};
|
};
|
||||||
@@ -311,49 +314,13 @@ impl<T: Runtime> Client<T> {
|
|||||||
.and_then(|module| module.call(C::FUNCTION, call))?)
|
.and_then(|module| module.call(C::FUNCTION, call))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an payload for an extrinsic.
|
|
||||||
///
|
|
||||||
/// If `nonce` is `None` the nonce will be fetched from the chain.
|
|
||||||
pub async fn create_payload<C: Call<T>>(
|
|
||||||
&self,
|
|
||||||
call: C,
|
|
||||||
account_id: &<T as System>::AccountId,
|
|
||||||
nonce: Option<T::Index>,
|
|
||||||
) -> Result<SignedPayload<T>, Error>
|
|
||||||
where
|
|
||||||
<<T::Extra as SignedExtra<T>>::Extra as SignedExtension>::AdditionalSigned:
|
|
||||||
Send + Sync,
|
|
||||||
{
|
|
||||||
let account_nonce = if let Some(nonce) = nonce {
|
|
||||||
nonce
|
|
||||||
} else {
|
|
||||||
self.account(account_id, None).await?.nonce
|
|
||||||
};
|
|
||||||
let spec_version = self.runtime_version.spec_version;
|
|
||||||
let tx_version = self.runtime_version.transaction_version;
|
|
||||||
let genesis_hash = self.genesis_hash;
|
|
||||||
let call = self.encode(call)?;
|
|
||||||
let extra: T::Extra =
|
|
||||||
T::Extra::new(spec_version, tx_version, account_nonce, genesis_hash);
|
|
||||||
let raw_payload = SignedPayload::<T>::new(call, extra.extra())?;
|
|
||||||
Ok(raw_payload)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates an unsigned extrinsic.
|
/// Creates an unsigned extrinsic.
|
||||||
pub async fn create_unsigned<C: Call<T> + Send + Sync>(
|
pub fn create_unsigned<C: Call<T> + Send + Sync>(
|
||||||
&self,
|
&self,
|
||||||
call: C,
|
call: C,
|
||||||
account_id: &<T as System>::AccountId,
|
) -> Result<UncheckedExtrinsic<T>, Error> {
|
||||||
nonce: Option<T::Index>,
|
let call = self.encode(call)?;
|
||||||
) -> Result<UncheckedExtrinsic<T>, Error>
|
Ok(extrinsic::create_unsigned::<T>(call))
|
||||||
where
|
|
||||||
<<T::Extra as SignedExtra<T>>::Extra as SignedExtension>::AdditionalSigned:
|
|
||||||
Send + Sync,
|
|
||||||
{
|
|
||||||
let payload = self.create_payload(call, account_id, nonce).await?;
|
|
||||||
let (call, _, _) = payload.deconstruct();
|
|
||||||
let unsigned = UncheckedExtrinsic::<T>::new_unsigned(call);
|
|
||||||
Ok(unsigned)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a signed extrinsic.
|
/// Creates a signed extrinsic.
|
||||||
@@ -366,10 +333,20 @@ impl<T: Runtime> Client<T> {
|
|||||||
<<T::Extra as SignedExtra<T>>::Extra as SignedExtension>::AdditionalSigned:
|
<<T::Extra as SignedExtra<T>>::Extra as SignedExtension>::AdditionalSigned:
|
||||||
Send + Sync,
|
Send + Sync,
|
||||||
{
|
{
|
||||||
let payload = self
|
let account_nonce = if let Some(nonce) = signer.nonce() {
|
||||||
.create_payload(call, signer.account_id(), signer.nonce())
|
nonce
|
||||||
.await?;
|
} else {
|
||||||
let signed = signer.sign(payload).await?;
|
self.account(signer.account_id(), None).await?.nonce
|
||||||
|
};
|
||||||
|
let call = self.encode(call)?;
|
||||||
|
let signed = extrinsic::create_signed(
|
||||||
|
&self.runtime_version,
|
||||||
|
self.genesis_hash,
|
||||||
|
account_nonce,
|
||||||
|
call,
|
||||||
|
signer,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
Ok(signed)
|
Ok(signed)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,19 +456,11 @@ impl codec::Encode for Encoded {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use codec::Encode;
|
use sp_core::storage::{
|
||||||
use sp_core::{
|
well_known_keys,
|
||||||
storage::{
|
StorageKey,
|
||||||
well_known_keys,
|
|
||||||
StorageKey,
|
|
||||||
},
|
|
||||||
Pair,
|
|
||||||
};
|
};
|
||||||
use sp_keyring::{
|
use sp_keyring::AccountKeyring;
|
||||||
AccountKeyring,
|
|
||||||
Ed25519Keyring,
|
|
||||||
};
|
|
||||||
use sp_runtime::MultiSignature;
|
|
||||||
use substrate_subxt_client::{
|
use substrate_subxt_client::{
|
||||||
DatabaseConfig,
|
DatabaseConfig,
|
||||||
KeystoreConfig,
|
KeystoreConfig,
|
||||||
@@ -640,47 +609,4 @@ mod tests {
|
|||||||
let mut blocks = client.subscribe_finalized_blocks().await.unwrap();
|
let mut blocks = client.subscribe_finalized_blocks().await.unwrap();
|
||||||
blocks.next().await;
|
blocks.next().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_std::test]
|
|
||||||
async fn test_create_raw_payload() {
|
|
||||||
let signer_pair = Ed25519Keyring::Alice.pair();
|
|
||||||
let signer_account_id = Ed25519Keyring::Alice.to_account_id();
|
|
||||||
let dest = AccountKeyring::Bob.to_account_id().into();
|
|
||||||
|
|
||||||
let (client, _) = test_client().await;
|
|
||||||
|
|
||||||
// create raw payload with AccoundId and sign it
|
|
||||||
let raw_payload = client
|
|
||||||
.create_payload(
|
|
||||||
balances::TransferCall {
|
|
||||||
to: &dest,
|
|
||||||
amount: 10_000,
|
|
||||||
},
|
|
||||||
&signer_account_id,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let raw_signature = signer_pair.sign(raw_payload.encode().as_slice());
|
|
||||||
let raw_multisig = MultiSignature::from(raw_signature);
|
|
||||||
|
|
||||||
// create signature with Xtbuilder
|
|
||||||
let signer = PairSigner::new(Ed25519Keyring::Alice.pair());
|
|
||||||
let xt_multi_sig = client
|
|
||||||
.create_signed(
|
|
||||||
balances::TransferCall {
|
|
||||||
to: &dest,
|
|
||||||
amount: 10_000,
|
|
||||||
},
|
|
||||||
&signer,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.signature
|
|
||||||
.unwrap()
|
|
||||||
.1;
|
|
||||||
|
|
||||||
// compare signatures
|
|
||||||
assert_eq!(raw_multisig, xt_multi_sig);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-16
@@ -27,7 +27,7 @@ use sp_runtime::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
extra::{
|
extrinsic::{
|
||||||
DefaultExtra,
|
DefaultExtra,
|
||||||
SignedExtra,
|
SignedExtra,
|
||||||
},
|
},
|
||||||
@@ -40,7 +40,6 @@ use crate::{
|
|||||||
sudo::Sudo,
|
sudo::Sudo,
|
||||||
system::System,
|
system::System,
|
||||||
},
|
},
|
||||||
Encoded,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Runtime trait.
|
/// Runtime trait.
|
||||||
@@ -51,20 +50,6 @@ pub trait Runtime: System + Sized + Send + Sync + 'static {
|
|||||||
type Extra: SignedExtra<Self> + Send + Sync + 'static;
|
type Extra: SignedExtra<Self> + Send + Sync + 'static;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extra type.
|
|
||||||
pub type Extra<T> = <<T as Runtime>::Extra as SignedExtra<T>>::Extra;
|
|
||||||
|
|
||||||
/// UncheckedExtrinsic type.
|
|
||||||
pub type UncheckedExtrinsic<T> = sp_runtime::generic::UncheckedExtrinsic<
|
|
||||||
<T as System>::Address,
|
|
||||||
Encoded,
|
|
||||||
<T as Runtime>::Signature,
|
|
||||||
Extra<T>,
|
|
||||||
>;
|
|
||||||
|
|
||||||
/// SignedPayload type.
|
|
||||||
pub type SignedPayload<T> = sp_runtime::generic::SignedPayload<Encoded, Extra<T>>;
|
|
||||||
|
|
||||||
/// Concrete type definitions compatible with those in the default substrate `node_runtime`
|
/// Concrete type definitions compatible with those in the default substrate `node_runtime`
|
||||||
///
|
///
|
||||||
/// # Note
|
/// # Note
|
||||||
|
|||||||
Reference in New Issue
Block a user