mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-30 18:57:57 +00:00
a0cb14aa4f
* start migrating, broken * first iteration of updating * fmt and clippy * add Composite<u32> decoding via scale value patch * bump scale type gen versions * fix decoding with new scale decode * compiling with changed deps * core utils, condig, client, metadata * core crate compiling * signer crate no once lock * add core to no-std-tests, change imports * broken commit, start pulling everything together in subxt * port more things to subxt * events in core crate, extrinsics sadly much more difficult * almost all examples pass again * dynamic values fix in examples * fix no std issue and fmt * remove unused dependencies * fix lightclient impl * runtime version refactor * formatting and addressing nits * more comments addressed * update wasm example and no-std-signer tests * other nits and error impl on signer errors * fix feature flag * fix runtime version refactor * fix doc links * fix integration tests * fix feature flag gated client state * fix native feature in CI * fix lightclient utils * make imports more lean in subxt-core * integrate changes from subxt-core imports into subxt * other changes in subxt simplify imports more * fix and docs * doc false for cli * fix clippy * remove events block hash in tests * codegen no-std support in generated code * export alloc crate for no-std codegen * fix doc test * implement James comments * remove std traits, use core traits instead * address nits * remove unusued dep in no-std tests * fix Box import in no_std * sp-crypto-hashing instead of sp-core-hashing * bump scale-typegen, add no std codegen tests * fix some things * replace unmaintained derivative with derive_where to remove non-canonical warnings * fmt * remove unused dep * fix deps * update artifacts to fix type ID mismatches * bump to latest scale-typegen --------- Co-authored-by: James Wilson <james@jsdw.me>
108 lines
3.8 KiB
Rust
108 lines
3.8 KiB
Rust
// Copyright 2019-2023 Parity Technologies (UK) Ltd.
|
|
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
|
// see LICENSE for license details.
|
|
|
|
use scale_decode::DecodeAsType;
|
|
use scale_encode::EncodeAsType;
|
|
|
|
// Dev note: This and related bits taken from `sp_runtime::generic::Era`
|
|
/// An era to describe the longevity of a transaction.
|
|
#[derive(
|
|
PartialEq,
|
|
Default,
|
|
Eq,
|
|
Clone,
|
|
Copy,
|
|
Debug,
|
|
serde::Serialize,
|
|
serde::Deserialize,
|
|
DecodeAsType,
|
|
EncodeAsType,
|
|
scale_info::TypeInfo,
|
|
)]
|
|
pub enum Era {
|
|
/// The transaction is valid forever. The genesis hash must be present in the signed content.
|
|
#[default]
|
|
Immortal,
|
|
|
|
/// The transaction will expire. Use [`Era::mortal`] to construct this with correct values.
|
|
///
|
|
/// When used on `FRAME`-based runtimes, `period` cannot exceed `BlockHashCount` parameter
|
|
/// of `system` module.
|
|
Mortal {
|
|
/// The number of blocks that the tx will be valid for after the checkpoint block
|
|
/// hash found in the signer payload.
|
|
period: u64,
|
|
/// The phase in the period that this transaction's lifetime begins (and, importantly,
|
|
/// implies which block hash is included in the signature material). If the `period` is
|
|
/// greater than 1 << 12, then it will be a factor of the times greater than 1<<12 that
|
|
/// `period` is.
|
|
phase: u64,
|
|
},
|
|
}
|
|
|
|
// E.g. with period == 4:
|
|
// 0 10 20 30 40
|
|
// 0123456789012345678901234567890123456789012
|
|
// |...|
|
|
// authored -/ \- expiry
|
|
// phase = 1
|
|
// n = Q(current - phase, period) + phase
|
|
impl Era {
|
|
/// Create a new era based on a period (which should be a power of two between 4 and 65536
|
|
/// inclusive) and a block number on which it should start (or, for long periods, be shortly
|
|
/// after the start).
|
|
///
|
|
/// If using `Era` in the context of `FRAME` runtime, make sure that `period`
|
|
/// does not exceed `BlockHashCount` parameter passed to `system` module, since that
|
|
/// prunes old blocks and renders transactions immediately invalid.
|
|
pub fn mortal(period: u64, current: u64) -> Self {
|
|
let period = period
|
|
.checked_next_power_of_two()
|
|
.unwrap_or(1 << 16)
|
|
.clamp(4, 1 << 16);
|
|
let phase = current % period;
|
|
let quantize_factor = (period >> 12).max(1);
|
|
let quantized_phase = phase / quantize_factor * quantize_factor;
|
|
|
|
Self::Mortal {
|
|
period,
|
|
phase: quantized_phase,
|
|
}
|
|
}
|
|
}
|
|
|
|
// Both copied from `sp_runtime::generic::Era`; this is the wire interface and so
|
|
// it's really the most important bit here.
|
|
impl codec::Encode for Era {
|
|
fn encode_to<T: codec::Output + ?Sized>(&self, output: &mut T) {
|
|
match self {
|
|
Self::Immortal => output.push_byte(0),
|
|
Self::Mortal { period, phase } => {
|
|
let quantize_factor = (*period >> 12).max(1);
|
|
let encoded = (period.trailing_zeros() - 1).clamp(1, 15) as u16
|
|
| ((phase / quantize_factor) << 4) as u16;
|
|
encoded.encode_to(output);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
impl codec::Decode for Era {
|
|
fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
|
|
let first = input.read_byte()?;
|
|
if first == 0 {
|
|
Ok(Self::Immortal)
|
|
} else {
|
|
let encoded = first as u64 + ((input.read_byte()? as u64) << 8);
|
|
let period = 2 << (encoded % (1 << 4));
|
|
let quantize_factor = (period >> 12).max(1);
|
|
let phase = (encoded >> 4) * quantize_factor;
|
|
if period >= 4 && phase < period {
|
|
Ok(Self::Mortal { period, phase })
|
|
} else {
|
|
Err("Invalid period and phase".into())
|
|
}
|
|
}
|
|
}
|
|
}
|