Skip to main content

๐Ÿงฉ XP Traits Architecture

pallet-xp is built around a trait-driven architecture.

Instead of placing all logic inside one large pallet implementation, responsibilities are separated into focused XP traits from the frame_suite::xp family.

This makes the system:

  • modular
  • composable
  • easier to test
  • easier to integrate across pallets
  • safer to extend over time

Each trait represents a specific capability of the XP system.


Why Traits Matterโ€‹

XP is not just storage.

It is a runtime-native identity system with:

  • ownership
  • execution
  • reputation growth
  • reserve and lock constraints
  • lifecycle management

A monolithic design would make this difficult to maintain.

Traits solve this by separating concerns cleanly โœจ


Core XP Trait Familyโ€‹

TraitResponsibilityFocus
BeginXpXP initialization entrypointControlled creation
XpSystemRead/query XP stateValidation + inspection
XpOwnerOwnership controlAuthorization
XpMutateCreate + earn XPMutation + Pulse
XpReserveReserve XPSoft constraints
XpLockLock XPHard constraints
XpReapRemove XPLifecycle termination

Additional helper traits:

Helper TraitPurpose
DiscreteAccumulatorPulse step progression

These traits make the pallet modular instead of monolithic.


1. BeginXpโ€‹

BeginXp is the safe initialization entrypoint for XP identities.

Its main purpose is:

ensure a reaped XpId can never be initialized again

Unlike XpMutate, which handles normal creation and updates, BeginXp first checks reaping history before allowing initialization.

This guarantees lifecycle finality and prevents resurrection attacks ๐Ÿงน

Relationship with XpMutateโ€‹

TraitResponsibility
BeginXpSafe first-time initialization with reap protection
XpMutateStandard creation, earning, updates, reset, slashing

Use:

  • BeginXp -> to safely start a given XP Key.
  • XpMutate -> for normal lifecycle operations

Key Methodโ€‹

MethodSignatureDescription
begin_xpfn begin_xp(Owner, Key, Xp) -> DispatchResultCreates XP only if the given key was never reaped

Why It Mattersโ€‹

Without BeginXp, deleted XP could be recreated.

BeginXp ensures:

  • reaping stays final
  • deleted identities stay deleted
  • XP lifecycle remains safe ๐Ÿ”

2. XpSystemโ€‹

XpSystem provides the read-only foundation of the XP layer.

It answers:

What XP exists and what is its current state?

Everything else depends on this trait.

Key Methodsโ€‹

MethodSignatureDescription
xp_existsfn xp_exists(XpKey) -> DispatchResultValidates whether an XP identity exists
has_minimum_xpfn has_minimum_xp(XpKey) -> DispatchResultChecks minimum XP threshold requirements
get_liquid_xpfn get_liquid_xp(XpKey) -> Result<Points, DispatchError>Returns liquid XP after constraints
get_usable_xpfn get_usable_xp(XpKey) -> Result<Points, DispatchError>Returns total usable XP

Why It Mattersโ€‹

Every XP operation starts here ๐Ÿ”

Before mutation, reserve, lock, or reap:

the runtime must first validate that the XP identity exists.

This is the read foundation of the pallet.


3. XpOwnerโ€‹

XpOwner manages ownership and execution authorization.

It defines:

who controls which XP identity

This is the trust boundary of the system.

Key Methodsโ€‹

MethodSignatureDescription
is_ownerfn is_owner(Owner, XpKey) -> DispatchResultVerifies ownership of an XP identity
xp_of_ownerfn xp_of_owner(Owner) -> Result<Vec<XpKey>, DispatchError>Returns all XP identities owned by an account
xp_key_genfn xp_key_gen(Owner, XpStruct) -> Result<XpKey, DispatchError>Returns a deterministic XpKey via owner's account nonce
transfer_ownerfn transfer_owner(Owner, XpKey, NewOwner) -> DispatchResultTransfers XP identity ownership

Why It Mattersโ€‹

This powers:

ensure(owner(origin, XpId))

Without XpOwner, XP execution would not be secure ๐Ÿ”

Ownership validation is the protocol trust boundary.


4. XpMutateโ€‹

XpMutate controls XP creation and progression.

This is where XP becomes dynamic.

It manages:

  • identity creation
  • earning XP
  • Pulse-based progression
  • lifecycle updates

Key Methodsโ€‹

MethodSignatureDescription
create_xpfn create_xp(Owner, XpKey) -> DispatchResultHigh-level helper for consistent XP creation
set_xpfn set_xp(XpKey, Points) -> DispatchResultDirectly updates stored XP (low-level)
earn_xpfn earn_xp(XpKey, Points) -> Result<Points, DispatchError>Main XP earning logic
quote_earn_xpfn quote_earn_xp(XpKey, Points) -> Result<Points, DispatchError>Simulates earned XP
slash_xpfn slash_xp(XpKey, Points) -> Result<Points, DispatchError>Reduces XP safely
reset_xpfn reset_xp(XpKey) -> Result<Points, DispatchError>Burns all liquid XP

Why It Mattersโ€‹

earn_xp() is one of the most important methods in the pallet ๐Ÿ“ˆ

It includes:

  • Pulse warmup
  • same-block protection
  • scaled rewards
  • lock-based acceleration

This is where XP becomes a reputation engine.


5. XpReserveโ€‹

XpReserve manages soft constraints.

Reserve means:

XP is allocated, but still usable

It represents intent rather than strict commitment.

Key Methodsโ€‹

MethodSignatureDescription
reserve_existsfn reserve_exists(XpKey, ReserveReason) -> DispatchResultValidates reserve existence
has_reservefn has_reserve(XpKey) -> DispatchResultChecks whether any reserve exists
get_reserve_xpfn get_reserve_xp(XpKey, ReserveReason) -> Result<Points, DispatchError>Returns reserved XP for a reason
total_reservedfn total_reserved(XpKey) -> Result<Points, DispatchError>Returns total reserved XP
set_reservefn set_reserve(XpKey, ReserveReason, Points) -> DispatchResultLow-level reserve mutation
reserve_xpfn reserve_xp(XpKey, ReserveReason, Points) -> DispatchResultHigh-level reserve creation
withdraw_reservefn withdraw_reserve(XpKey, ReserveReason) -> DispatchResultReleases full reserve back to liquid XP
withdraw_reserve_partialfn withdraw_reserve(XpKey, ReserveReason, Points) -> DispatchResultReleases partial reserve back to liquid XP
slash_reservefn slash_reserve(XpKey, ReserveReason, Points) -> Result<Points, DispatchError>Applies reserve penalties

Reserve Characteristicsโ€‹

PropertyMeaning
RestrictionSoft
Usable XPYes
PurposeAllocation
Pulse ImpactNone

Reserve is soft constraint logic ๐Ÿ“ฆ


6. XpLockโ€‹

XpLock manages hard constraints.

Lock means:

XP is committed and cannot be used

This represents stronger protocol guarantees.

Key Methodsโ€‹

MethodSignatureDescription
lock_existsfn lock_exists(XpKey, LockReason) -> DispatchResultValidates lock existence
has_lockfn has_lock(XpKey) -> DispatchResultChecks whether active locks exist
get_lock_xpfn get_lock_xp(XpKey, LockReason) -> Result<Points, DispatchError>Returns locked XP for a reason
total_lockedfn total_locked(XpKey) -> Result<Points, DispatchError>Returns total locked XP
set_lockfn set_lock(XpKey, LockReason, Points) -> DispatchResultLow-level lock mutation
lock_xpfn lock_xp(XpKey, LockReason, Points) -> DispatchResultHigh-level lock creation
withdraw_lockfn withdraw_lock(XpKey, LockReason) -> DispatchResultUnlocks XP
slash_lockfn slash_lock(XpKey, LockReason, Points) -> Result<Points, DispatchError>Applies lock penalties
burn_lockfn burn_lock(XpKey, LockReason) -> DispatchResultRemoves lock entry

Lock Characteristicsโ€‹

PropertyMeaning
RestrictionHard
Usable XPNo
PurposeCommitment
Pulse ImpactAccelerates future growth

Lock is hard constraint logic ๐Ÿ”’


7. XpReapโ€‹

XpReap manages permanent lifecycle removal.

It answers:

When should XP stop existing?

Reaping is identity deletion, not balance reduction.

Key Methodsโ€‹

MethodSignatureDescription
reap_xpfn reap_xp(XpKey) -> DispatchResultPermanently removes inactive XP
is_reapedfn is_reaped(XpKey) -> boolChecks whether XP was already reaped

Why It Mattersโ€‹

Reaping ensures:

  • abandoned XP does not remain forever
  • deleted identities cannot return
  • lifecycle rules remain enforceable

This keeps XP active, not passive ๐Ÿงน


Trait Relationshipsโ€‹

Traits are layered intentionally.

They depend on each other without becoming tightly coupled.


Design Principlesโ€‹

PrincipleMeaning
Single ResponsibilityEach trait owns one concern
ComposabilityPallets integrate only what they need
Runtime SafetyValidation and mutation stay isolated
ExtensibilityNew behavior can be added safely

This keeps the architecture maintainable and future-proof ๐Ÿš€


Final Insightโ€‹

๐Ÿงฉ Traits are what make pallet-xp programmable.

Storage gives XP persistence.

Traits give XP behavior.

Together, they create an identity-driven execution system, not just another balance pallet.


๐Ÿš€ Next Stepsโ€‹

To understand interoperability with balance-based pallets:

๐Ÿ‘‰ Architecture -> Fungible Adapter