ac_primitives/extrinsics/
extrinsic_v4.rs1use crate::OpaqueExtrinsic;
21use alloc::{format, vec::Vec};
22use codec::{Decode, Encode, Error, Input};
23use core::fmt;
24use scale_info::TypeInfo;
25#[allow(deprecated)]
26use sp_runtime::traits::Extrinsic;
27
28const V4: u8 = 4;
30
31#[allow(deprecated)]
32pub mod deprecated {
33 use super::*;
34 #[deprecated = "Use the `UncheckedExtrinsic` with Version 5 instead"]
38 #[derive(Clone, Eq, PartialEq)]
39
40 pub struct UncheckedExtrinsicV4<Address, Call, Signature, SignedExtra> {
41 pub signature: Option<(Address, Signature, SignedExtra)>,
45 pub function: Call,
47 }
48
49 impl<Address, Call, Signature, SignedExtra>
50 UncheckedExtrinsicV4<Address, Call, Signature, SignedExtra>
51 {
52 pub fn new_signed(
54 function: Call,
55 signed: Address,
56 signature: Signature,
57 extra: SignedExtra,
58 ) -> Self {
59 UncheckedExtrinsicV4 { signature: Some((signed, signature, extra)), function }
60 }
61
62 pub fn new_unsigned(function: Call) -> Self {
64 Self { signature: None, function }
65 }
66 }
67
68 impl<Address, Call, Signature, SignedExtra> Extrinsic
69 for UncheckedExtrinsicV4<Address, Call, Signature, SignedExtra>
70 where
71 Address: TypeInfo,
72 Signature: TypeInfo,
73 Call: TypeInfo,
74 SignedExtra: TypeInfo,
75 {
76 type Call = Call;
77
78 type SignaturePayload = (Address, Signature, SignedExtra);
79
80 fn is_signed(&self) -> Option<bool> {
81 Some(self.signature.is_some())
82 }
83
84 fn new(function: Call, signed_data: Option<Self::SignaturePayload>) -> Option<Self> {
85 Some(if let Some((address, signature, extra)) = signed_data {
86 Self::new_signed(function, address, signature, extra)
87 } else {
88 Self::new_unsigned(function)
89 })
90 }
91 }
92
93 impl<Address, Call, Signature, SignedExtra> fmt::Debug
94 for UncheckedExtrinsicV4<Address, Call, Signature, SignedExtra>
95 where
96 Address: fmt::Debug,
97 Signature: fmt::Debug,
98 Call: fmt::Debug,
99 SignedExtra: fmt::Debug,
100 {
101 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
102 write!(
103 f,
104 "UncheckedExtrinsic({:?}, {:?})",
105 self.signature.as_ref().map(|x| (&x.0, &x.2)),
106 self.function
107 )
108 }
109 }
110
111 impl<Address, Call, Signature, SignedExtra> Encode
113 for UncheckedExtrinsicV4<Address, Call, Signature, SignedExtra>
114 where
115 Address: Encode,
116 Signature: Encode,
117 Call: Encode,
118 SignedExtra: Encode,
119 {
120 fn encode(&self) -> Vec<u8> {
121 encode_with_vec_prefix::<Self, _>(|v| {
122 match self.signature.as_ref() {
123 Some(s) => {
124 v.push(V4 | 0b1000_0000);
125 s.encode_to(v);
126 },
127 None => {
128 v.push(V4 & 0b0111_1111);
129 },
130 }
131 self.function.encode_to(v);
132 })
133 }
134 }
135
136 impl<Address, Call, Signature, SignedExtra> Decode
138 for UncheckedExtrinsicV4<Address, Call, Signature, SignedExtra>
139 where
140 Address: Decode,
141 Signature: Decode,
142 Call: Decode,
143 SignedExtra: Decode,
144 {
145 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
146 let _length_do_not_remove_me_see_above: Vec<()> = Decode::decode(input)?;
151
152 let version = input.read_byte()?;
153
154 let is_signed = version & 0b1000_0000 != 0;
155 let version = version & 0b0111_1111;
156 if version != V4 {
157 return Err("Invalid transaction version".into())
158 }
159
160 Ok(UncheckedExtrinsicV4 {
161 signature: if is_signed { Some(Decode::decode(input)?) } else { None },
162 function: Decode::decode(input)?,
163 })
164 }
165 }
166
167 impl<Address, Call, Signature, SignedExtra> serde::Serialize
168 for UncheckedExtrinsicV4<Address, Call, Signature, SignedExtra>
169 where
170 Address: Encode,
171 Signature: Encode,
172 Call: Encode,
173 SignedExtra: Encode,
174 {
175 fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error>
176 where
177 S: ::serde::Serializer,
178 {
179 self.using_encoded(|bytes| impl_serde::serialize::serialize(bytes, seq))
180 }
181 }
182
183 impl<'a, Address, Call, Signature, SignedExtra> serde::Deserialize<'a>
185 for UncheckedExtrinsicV4<Address, Call, Signature, SignedExtra>
186 where
187 Address: Decode,
188 Signature: Decode,
189 Call: Decode,
190 SignedExtra: Decode,
191 {
192 fn deserialize<D>(de: D) -> Result<Self, D::Error>
193 where
194 D: serde::Deserializer<'a>,
195 {
196 let r = impl_serde::serialize::deserialize(de)?;
197 Decode::decode(&mut &r[..])
198 .map_err(|e| serde::de::Error::custom(format!("Decode error: {e}")))
199 }
200 }
201
202 impl<Address, Call, Signature, Extra>
204 From<UncheckedExtrinsicV4<Address, Call, Signature, Extra>> for OpaqueExtrinsic
205 where
206 Address: Encode,
207 Signature: Encode,
208 Call: Encode,
209 Extra: Encode,
210 {
211 fn from(extrinsic: UncheckedExtrinsicV4<Address, Call, Signature, Extra>) -> Self {
212 Self::from_bytes(extrinsic.encode().as_slice()).expect(
213 "both OpaqueExtrinsic and UncheckedExtrinsic have encoding that is compatible with \
214 raw Vec<u8> encoding; qed",
215 )
216 }
217 }
218
219 fn encode_with_vec_prefix<T: Encode, F: Fn(&mut Vec<u8>)>(encoder: F) -> Vec<u8> {
221 let size = core::mem::size_of::<T>();
222 let reserve = match size {
223 0..=0b0011_1111 => 1,
224 0b0100_0000..=0b0011_1111_1111_1111 => 2,
225 _ => 4,
226 };
227 let mut v = Vec::with_capacity(reserve + size);
228 v.resize(reserve, 0);
229 encoder(&mut v);
230
231 let mut length: Vec<()> = Vec::new();
234 length.resize(v.len() - reserve, ());
235 length.using_encoded(|s| {
236 v.splice(0..reserve, s.iter().cloned());
237 });
238
239 v
240 }
241}