Move serai-client off serai-runtime, MIT licensing it

Uses a full-fledged serai-abi to do so.

Removes use of UncheckedExtrinsic as a pointlessly (for us) length-prefixed
block with a more complicated signing algorithm than advantageous.

In the future, we should considering consolidating the various primitives
crates. I'm not convinced we benefit from one primitives crate per pallet.
This commit is contained in:
Luke Parker
2023-12-07 02:30:09 -05:00
parent 6416e0079b
commit c511a54d18
38 changed files with 484 additions and 378 deletions

View File

@@ -25,8 +25,10 @@ sp-application-crypto = { git = "https://github.com/serai-dex/substrate", defaul
sp-core = { git = "https://github.com/serai-dex/substrate", default-features = false }
sp-runtime = { git = "https://github.com/serai-dex/substrate", default-features = false }
frame-support = { git = "https://github.com/serai-dex/substrate", default-features = false }
[features]
std = ["zeroize", "scale/std", "borsh?/std", "serde?/std", "scale-info/std", "sp-core/std", "sp-runtime/std"]
std = ["zeroize", "scale/std", "borsh?/std", "serde?/std", "scale-info/std", "sp-core/std", "sp-runtime/std", "frame-support/std"]
borsh = ["dep:borsh"]
serde = ["dep:serde"]
default = ["std"]

View File

@@ -50,6 +50,7 @@ pub fn borsh_deserialize_signature<R: borsh::io::Read>(
Ok(Signature(signature))
}
// TODO: Remove this for solely Public?
#[derive(
Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Encode, Decode, MaxEncodedLen, TypeInfo,
)]

View File

@@ -32,6 +32,9 @@ pub use balance::*;
mod account;
pub use account::*;
mod tx;
pub use tx::*;
#[cfg(feature = "borsh")]
pub fn borsh_serialize_bounded_vec<W: borsh::io::Write, T: BorshSerialize, const B: u32>(
bounded: &BoundedVec<T, ConstU32<B>>,

View File

@@ -0,0 +1,122 @@
use scale::Encode;
use sp_core::sr25519::{Public, Signature};
use sp_runtime::traits::Verify;
use crate::SeraiAddress;
trait TransactionMember:
Clone + PartialEq + Eq + core::fmt::Debug + scale::Encode + scale::Decode + scale_info::TypeInfo
{
}
impl<
T: Clone
+ PartialEq
+ Eq
+ core::fmt::Debug
+ scale::Encode
+ scale::Decode
+ scale_info::TypeInfo,
> TransactionMember for T
{
}
#[allow(private_bounds)]
#[derive(Clone, PartialEq, Eq, Debug, scale::Encode, scale::Decode, scale_info::TypeInfo)]
pub struct Transaction<Call: TransactionMember, Extra: TransactionMember> {
pub call: Call,
pub signature: Option<(SeraiAddress, Signature, Extra)>,
}
#[cfg(feature = "serde")]
mod _serde {
use scale::Encode;
use serde::{ser::*, de::*};
use super::*;
impl<Call: TransactionMember, Extra: TransactionMember> Serialize for Transaction<Call, Extra> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let encoded = self.encode();
serializer.serialize_bytes(&encoded)
}
}
#[cfg(feature = "std")]
impl<'a, Call: TransactionMember, Extra: TransactionMember> Deserialize<'a>
for Transaction<Call, Extra>
{
fn deserialize<D: Deserializer<'a>>(de: D) -> Result<Self, D::Error> {
let bytes = sp_core::bytes::deserialize(de)?;
scale::Decode::decode(&mut &bytes[..])
.map_err(|e| serde::de::Error::custom(format!("invalid transaction: {}", e)))
}
}
}
impl<Call: TransactionMember, Extra: TransactionMember> sp_runtime::traits::Extrinsic
for Transaction<Call, Extra>
{
type Call = Call;
type SignaturePayload = (SeraiAddress, Signature, Extra);
fn is_signed(&self) -> Option<bool> {
Some(self.signature.is_some())
}
fn new(call: Call, signature: Option<Self::SignaturePayload>) -> Option<Self> {
Some(Self { call, signature })
}
}
impl<Call: TransactionMember, Extra: TransactionMember> frame_support::traits::ExtrinsicCall
for Transaction<Call, Extra>
{
fn call(&self) -> &Call {
&self.call
}
}
impl<Call: TransactionMember, Extra: TransactionMember> sp_runtime::traits::ExtrinsicMetadata
for Transaction<Call, Extra>
where
Extra: sp_runtime::traits::SignedExtension,
{
type SignedExtensions = Extra;
const VERSION: u8 = 0;
}
impl<Call: TransactionMember, Extra: TransactionMember> frame_support::dispatch::GetDispatchInfo
for Transaction<Call, Extra>
where
Call: frame_support::dispatch::GetDispatchInfo,
{
fn get_dispatch_info(&self) -> frame_support::dispatch::DispatchInfo {
self.call.get_dispatch_info()
}
}
impl<Call: TransactionMember, Extra: TransactionMember> sp_runtime::traits::BlindCheckable
for Transaction<Call, Extra>
where
Extra: sp_runtime::traits::SignedExtension,
{
type Checked = sp_runtime::generic::CheckedExtrinsic<Public, Call, Extra>;
fn check(
self,
) -> Result<Self::Checked, sp_runtime::transaction_validity::TransactionValidityError> {
Ok(match self.signature {
Some((signer, signature, extra)) => {
if !signature.verify(
(&self.call, &extra, extra.additional_signed()?).encode().as_slice(),
&signer.into(),
) {
Err(sp_runtime::transaction_validity::InvalidTransaction::BadProof)?
}
sp_runtime::generic::CheckedExtrinsic {
signed: Some((signer.into(), extra)),
function: self.call,
}
}
None => sp_runtime::generic::CheckedExtrinsic { signed: None, function: self.call },
})
}
}