mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-28 10:57:56 +00:00
Submit (& sign) extrinsics from the runtime. (#3514)
* Abstract constructing extrinsic and signing. * Initial impl of signer. * Implement get payload. * Clean up the code. * Improve docs. * Bump version. * Update core/sr-primitives/src/generic/unchecked_extrinsic.rs Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * Fix tests & address grumbles. * Fix build. * Fix runtime tests. * Fix bound test. * Fix bound test.
This commit is contained in:
committed by
Gavin Wood
parent
0cae7217d8
commit
feecfc856d
@@ -27,7 +27,7 @@ mod digest;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub use self::unchecked_extrinsic::UncheckedExtrinsic;
|
||||
pub use self::unchecked_extrinsic::{UncheckedExtrinsic, SignedPayload};
|
||||
pub use self::era::{Era, Phase};
|
||||
pub use self::checked_extrinsic::CheckedExtrinsic;
|
||||
pub use self::header::Header;
|
||||
|
||||
@@ -72,12 +72,22 @@ impl<Address, Call, Signature, Extra: SignedExtension> Extrinsic
|
||||
{
|
||||
type Call = Call;
|
||||
|
||||
type SignaturePayload = (
|
||||
Address,
|
||||
Signature,
|
||||
Extra,
|
||||
);
|
||||
|
||||
fn is_signed(&self) -> Option<bool> {
|
||||
Some(self.signature.is_some())
|
||||
}
|
||||
|
||||
fn new_unsigned(function: Call) -> Option<Self> {
|
||||
Some(UncheckedExtrinsic::new_unsigned(function))
|
||||
fn new(function: Call, signed_data: Option<Self::SignaturePayload>) -> Option<Self> {
|
||||
Some(if let Some((address, signature, extra)) = signed_data {
|
||||
UncheckedExtrinsic::new_signed(function, address, signature, extra)
|
||||
} else {
|
||||
UncheckedExtrinsic::new_unsigned(function)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,21 +108,18 @@ where
|
||||
fn check(self, lookup: &Lookup) -> Result<Self::Checked, &'static str> {
|
||||
Ok(match self.signature {
|
||||
Some((signed, signature, extra)) => {
|
||||
let additional_signed = extra.additional_signed()?;
|
||||
let raw_payload = (self.function, extra, additional_signed);
|
||||
let signed = lookup.lookup(signed)?;
|
||||
let raw_payload = SignedPayload::new(self.function, extra)?;
|
||||
if !raw_payload.using_encoded(|payload| {
|
||||
if payload.len() > 256 {
|
||||
signature.verify(&blake2_256(payload)[..], &signed)
|
||||
} else {
|
||||
signature.verify(payload, &signed)
|
||||
}
|
||||
signature.verify(payload, &signed)
|
||||
}) {
|
||||
return Err(crate::BAD_SIGNATURE)
|
||||
}
|
||||
|
||||
let (function, extra, _) = raw_payload.deconstruct();
|
||||
CheckedExtrinsic {
|
||||
signed: Some((signed, raw_payload.1)),
|
||||
function: raw_payload.0,
|
||||
signed: Some((signed, extra)),
|
||||
function,
|
||||
}
|
||||
}
|
||||
None => CheckedExtrinsic {
|
||||
@@ -123,6 +130,59 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// A payload that has been signed for an unchecked extrinsics.
|
||||
///
|
||||
/// Note that the payload that we sign to produce unchecked extrinsic signature
|
||||
/// is going to be different than the `SignaturePayload` - so the thing the extrinsic
|
||||
/// actually contains.
|
||||
pub struct SignedPayload<Call, Extra: SignedExtension>((
|
||||
Call,
|
||||
Extra,
|
||||
Extra::AdditionalSigned,
|
||||
));
|
||||
|
||||
impl<Call, Extra> SignedPayload<Call, Extra> where
|
||||
Call: Encode,
|
||||
Extra: SignedExtension,
|
||||
{
|
||||
/// Create new `SignedPayload`.
|
||||
///
|
||||
/// This function may fail if `additional_signed` of `Extra` is not available.
|
||||
pub fn new(call: Call, extra: Extra) -> Result<Self, &'static str> {
|
||||
let additional_signed = extra.additional_signed()?;
|
||||
let raw_payload = (call, extra, additional_signed);
|
||||
Ok(Self(raw_payload))
|
||||
}
|
||||
|
||||
/// Create new `SignedPayload` from raw components.
|
||||
pub fn from_raw(call: Call, extra: Extra, additional_signed: Extra::AdditionalSigned) -> Self {
|
||||
Self((call, extra, additional_signed))
|
||||
}
|
||||
|
||||
/// Deconstruct the payload into it's components.
|
||||
pub fn deconstruct(self) -> (Call, Extra, Extra::AdditionalSigned) {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<Call, Extra> Encode for SignedPayload<Call, Extra> where
|
||||
Call: Encode,
|
||||
Extra: SignedExtension,
|
||||
{
|
||||
/// Get an encoded version of this payload.
|
||||
///
|
||||
/// Payloads longer than 256 bytes are going to be `blake2_256`-hashed.
|
||||
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
self.0.using_encoded(|payload| {
|
||||
if payload.len() > 256 {
|
||||
f(&blake2_256(payload)[..])
|
||||
} else {
|
||||
f(payload)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<Address, Call, Signature, Extra> Decode
|
||||
for UncheckedExtrinsic<Address, Call, Signature, Extra>
|
||||
where
|
||||
|
||||
Reference in New Issue
Block a user