Redo primitives, abi

Consolidates all primitives into a single crate. We didn't benefit from its
fragmentation. I'm hesitant to say the new internal-organization is better (it
may be just as clunky), but it's at least in a single crate (not spread out
over micro-crates).

The ABI is the most distinct. We now entirely own it. Block header hashes don't
directly commit to any BABE data (avoiding potentially ~4 KB headers upon
session changes), and are hashed as borsh (a more widely used codec than
SCALE). There are still Substrate variants, using SCALE and with the BABE data,
but they're prunable from a protocol design perspective.

Defines a transaction as a Vec of Calls, allowing atomic operations.
This commit is contained in:
Luke Parker
2025-02-12 03:41:50 -05:00
parent 2f8ce15a92
commit 776e417fd2
49 changed files with 2225 additions and 2092 deletions

View File

@@ -1,38 +1,111 @@
use core::ops::{Add, Sub, Mul};
#[cfg(feature = "std")]
use zeroize::Zeroize;
#[cfg(feature = "borsh")]
use borsh::{BorshSerialize, BorshDeserialize};
#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};
use scale::{Encode, Decode, MaxEncodedLen};
use scale_info::TypeInfo;
use crate::coin::{ExternalCoin, Coin};
use crate::{Amount, Coin, ExternalCoin};
/// The type internally used to represent amounts.
// https://github.com/rust-lang/rust/issues/8995
pub type AmountRepr = u64;
/// The type used for balances (a Coin and Balance).
#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)]
#[cfg_attr(feature = "std", derive(Zeroize))]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Balance {
pub coin: Coin,
/// A wrapper used to represent amounts.
#[derive(
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Debug,
Zeroize,
BorshSerialize,
BorshDeserialize,
)]
pub struct Amount(pub AmountRepr);
impl Add for Amount {
type Output = Option<Amount>;
fn add(self, other: Amount) -> Option<Amount> {
self.0.checked_add(other.0).map(Amount)
}
}
impl Sub for Amount {
type Output = Option<Amount>;
fn sub(self, other: Amount) -> Option<Amount> {
self.0.checked_sub(other.0).map(Amount)
}
}
impl Mul for Amount {
type Output = Option<Amount>;
fn mul(self, other: Amount) -> Option<Amount> {
self.0.checked_mul(other.0).map(Amount)
}
}
/// An ExternalCoin and an Amount, forming a balance for an external coin.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize, BorshSerialize, BorshDeserialize)]
pub struct ExternalBalance {
/// The coin this is a balance for.
pub coin: ExternalCoin,
/// The amount of this balance.
pub amount: Amount,
}
/// The type used for balances (a Coin and Balance).
#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)]
#[cfg_attr(feature = "std", derive(Zeroize))]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ExternalBalance {
pub coin: ExternalCoin,
impl Add<Amount> for ExternalBalance {
type Output = Option<ExternalBalance>;
fn add(self, other: Amount) -> Option<ExternalBalance> {
(self.amount + other).map(|amount| ExternalBalance { coin: self.coin, amount })
}
}
impl Sub<Amount> for ExternalBalance {
type Output = Option<ExternalBalance>;
fn sub(self, other: Amount) -> Option<ExternalBalance> {
(self.amount - other).map(|amount| ExternalBalance { coin: self.coin, amount })
}
}
impl Mul<Amount> for ExternalBalance {
type Output = Option<ExternalBalance>;
fn mul(self, other: Amount) -> Option<ExternalBalance> {
(self.amount * other).map(|amount| ExternalBalance { coin: self.coin, amount })
}
}
/// A Coin and an Amount, forming a balance for a coin.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize, BorshSerialize, BorshDeserialize)]
pub struct Balance {
/// The coin this is a balance for.
pub coin: Coin,
/// The amount of this balance.
pub amount: Amount,
}
impl Add<Amount> for Balance {
type Output = Option<Balance>;
fn add(self, other: Amount) -> Option<Balance> {
(self.amount + other).map(|amount| Balance { coin: self.coin, amount })
}
}
impl Sub<Amount> for Balance {
type Output = Option<Balance>;
fn sub(self, other: Amount) -> Option<Balance> {
(self.amount - other).map(|amount| Balance { coin: self.coin, amount })
}
}
impl Mul<Amount> for Balance {
type Output = Option<Balance>;
fn mul(self, other: Amount) -> Option<Balance> {
(self.amount * other).map(|amount| Balance { coin: self.coin, amount })
}
}
impl From<ExternalBalance> for Balance {
fn from(balance: ExternalBalance) -> Self {
Balance { coin: balance.coin.into(), amount: balance.amount }
@@ -49,25 +122,3 @@ impl TryFrom<Balance> for ExternalBalance {
}
}
}
// TODO: these impl either should be removed or return errors in case of overflows
impl Add<Amount> for Balance {
type Output = Balance;
fn add(self, other: Amount) -> Balance {
Balance { coin: self.coin, amount: self.amount + other }
}
}
impl Sub<Amount> for Balance {
type Output = Balance;
fn sub(self, other: Amount) -> Balance {
Balance { coin: self.coin, amount: self.amount - other }
}
}
impl Mul<Amount> for Balance {
type Output = Balance;
fn mul(self, other: Amount) -> Balance {
Balance { coin: self.coin, amount: self.amount * other }
}
}