mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 07:37:57 +00:00
Make UncheckedExtrinsic encode more readable (#9531)
Actually this will cost us another allocation, but before this wasn't really safe. Assuming that we only need `size_of` bytes for the encoding of the tx could have ended with an invalid encoding.
This commit is contained in:
@@ -36,28 +36,3 @@ pub use self::{
|
||||
header::Header,
|
||||
unchecked_extrinsic::{SignedPayload, UncheckedExtrinsic},
|
||||
};
|
||||
|
||||
use crate::codec::Encode;
|
||||
use sp_std::prelude::*;
|
||||
|
||||
fn encode_with_vec_prefix<T: Encode, F: Fn(&mut Vec<u8>)>(encoder: F) -> Vec<u8> {
|
||||
let size = ::sp_std::mem::size_of::<T>();
|
||||
let reserve = match size {
|
||||
0..=0b00111111 => 1,
|
||||
0b01000000..=0b00111111_11111111 => 2,
|
||||
_ => 4,
|
||||
};
|
||||
let mut v = Vec::with_capacity(reserve + size);
|
||||
v.resize(reserve, 0);
|
||||
encoder(&mut v);
|
||||
|
||||
// need to prefix with the total length to ensure it's binary compatible with
|
||||
// Vec<u8>.
|
||||
let mut length: Vec<()> = Vec::new();
|
||||
length.resize(v.len() - reserve, ());
|
||||
length.using_encoded(|s| {
|
||||
v.splice(0..reserve, s.iter().cloned());
|
||||
});
|
||||
|
||||
v
|
||||
}
|
||||
|
||||
@@ -228,19 +228,29 @@ where
|
||||
Extra: SignedExtension,
|
||||
{
|
||||
fn encode(&self) -> Vec<u8> {
|
||||
super::encode_with_vec_prefix::<Self, _>(|v| {
|
||||
// 1 byte version id.
|
||||
match self.signature.as_ref() {
|
||||
Some(s) => {
|
||||
v.push(EXTRINSIC_VERSION | 0b1000_0000);
|
||||
s.encode_to(v);
|
||||
},
|
||||
None => {
|
||||
v.push(EXTRINSIC_VERSION & 0b0111_1111);
|
||||
},
|
||||
}
|
||||
self.function.encode_to(v);
|
||||
})
|
||||
let mut tmp = Vec::with_capacity(sp_std::mem::size_of::<Self>());
|
||||
|
||||
// 1 byte version id.
|
||||
match self.signature.as_ref() {
|
||||
Some(s) => {
|
||||
tmp.push(EXTRINSIC_VERSION | 0b1000_0000);
|
||||
s.encode_to(&mut tmp);
|
||||
},
|
||||
None => {
|
||||
tmp.push(EXTRINSIC_VERSION & 0b0111_1111);
|
||||
},
|
||||
}
|
||||
self.function.encode_to(&mut tmp);
|
||||
|
||||
let compact_len = codec::Compact::<u32>(tmp.len() as u32);
|
||||
|
||||
// Allocate the output buffer with the correct length
|
||||
let mut output = Vec::with_capacity(compact_len.size_hint() + tmp.len());
|
||||
|
||||
compact_len.encode_to(&mut output);
|
||||
output.extend(tmp);
|
||||
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user