feat(types): Phase 2/3 prep — 3 custom Charon pallet traits v0.0.3

Day 1 unblock surface extended con custom pallet traits para Phase 2-3 work
all Substrate-free (no Substrate deps pulled yet, that's Phase 1.2).

## New trait surface (origin-chain-types::pallets)

### OriginProvenance (Phase 2.1, CHN-7)
- attest_validator_signed: institutional/Foundation wallet attestation
- batch_attest: bounded 64-item batch (Pi 5 block-weight aware)
- provenance_exists: cheap duplicate-check query (no full fetch)

### OriginFees (Phase 2.4, CHN-8)
- fee_for_extrinsic: storage-aware fee computation (uses tier_assertion)
- estimate_fee: pure off-chain RPC dry-run helper
- burn_basis_points: per-operation burn rate canonical (CHN-2 matrix)

### OriginValidatorEconomy (Phase 3.5, CHN-3)
- distribute_rewards: epoch-based pro-rata desde 40% Ecosystem Pool
- slash_validator: SlashReason taxonomy canonical
- validator_commission_bps: nominator delegation read

### SlashReason enum
- Downtime | DoubleSign | Equivocation | TierFraud
- TierFraud variant enforces Inmutable #16 anti-clasista ON-CHAIN

## Workspace stats
- 46 tests passing (was 44, +3 SlashReason serde + distinctness +
  inmutable_16 enforcement)
- Build release clean
- origin-chain-runtime re-exports extended

Refs: CHN-3/7/8, Phase 2.1/2.4/3.5 of CHARON_ROADMAP_V1, Inmutable #16

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
davidherranandClaude Opus 4.6 committed 2026-05-20 08:08:28 -05:00
1 parent 2f47654418
commit 13db9a0698
4 files changed
+217 -1

No files matched your search

+2 -1
View File
@@ -39,7 +39,8 @@
pub use origin_chain_types::{
AccountId, AssetAttestation, AssetHash, AssetQualityTier, BridgeDestination, ChainBridge,
ChainError, FeeCalculator, ForeignTxId, GovernanceProposal, HardwareTier, Ogc, OgcLedger,
OperationKind, ProposalId, ProvenanceLedger, Signature, Vote, VoteStance,
OperationKind, OriginFees, OriginProvenance, OriginValidatorEconomy, ProposalId,
ProvenanceLedger, Signature, SlashReason, Vote, VoteStance,
};
/// Canonical runtime configuration. Substrate `Config` traits implement when
+2
View File
@@ -42,6 +42,7 @@ pub mod errors;
pub mod fees;
pub mod governance;
pub mod ogc;
pub mod pallets;
pub mod provenance;
pub mod tiers;
@@ -51,6 +52,7 @@ pub use errors::ChainError;
pub use fees::{FeeCalculator, OperationKind};
pub use governance::{GovernanceProposal, ProposalId, Vote, VoteStance};
pub use ogc::{Ogc, OgcLedger};
pub use pallets::{OriginFees, OriginProvenance, OriginValidatorEconomy, SlashReason};
pub use provenance::{AssetAttestation, ProvenanceLedger};
pub use tiers::{AssetQualityTier, HardwareTier};
+164
View File
@@ -0,0 +1,164 @@
//! Custom Charon pallet traits — Day 1 unblock surfaces for Phase 2-3 work.
//!
//! Three custom pallets ship as part of Charon's domain authority (NOT inherited
//! from Substrate template):
//!
//! 1. [`OriginProvenance`] — asset attestation pallet (Phase 2.1, CHN-7)
//! 2. [`OriginFees`] — multi-tier fee matrix pallet (Phase 2.4, CHN-8)
//! 3. [`OriginValidatorEconomy`] — NPoS slashing + rewards curve (Phase 3.5, CHN-3)
//!
//! Trait surfaces published Day 1 (this crate). Concrete pallet implementations
//! live in `pallet-origin-*` crates that will be added to the workspace at
//! their respective phases (Substrate deps required).
use crate::{AccountId, AssetAttestation, AssetHash, AssetQualityTier, ChainError, HardwareTier, Ogc, OperationKind};
// ============================================================================
// pallet-origin-provenance — CHN-7 asset attestation
// ============================================================================
/// Trait canonical for the Charon-custom asset provenance pallet (`pallet-origin-provenance`).
///
/// Extends the base `ProvenanceLedger` trait with pallet-specific operations:
/// validator-attested signing (institutional / Foundation wallet), batch
/// attestation for high-throughput minting (Trinity 3D batches), and
/// revocation queries (post-mint immutability respected per Inmutable #26).
pub trait OriginProvenance {
/// Attest an asset where the signer is a validator-level Foundation wallet
/// (e.g. OIT Nivel 3 institutional). Higher trust tier than user mints —
/// runtime fees may be discounted per CHN-8 policy.
fn attest_validator_signed(
&self,
attestation: AssetAttestation,
validator: &AccountId,
) -> Result<(), ChainError>;
/// Batch-attest a set of assets in a single extrinsic. Bounded length (max
/// 64 per call to avoid block-weight overrun on Pi 5 validators).
fn batch_attest(&self, attestations: Vec<AssetAttestation>) -> Result<u32, ChainError>;
/// Query whether an asset hash exists in the provenance ledger without
/// fetching the full attestation. Cheaper than `verify_provenance` —
/// useful for marketplace pre-mint duplicate checks.
fn provenance_exists(&self, hash: &AssetHash) -> bool;
}
// ============================================================================
// pallet-origin-fees — CHN-8 multi-tier fee matrix
// ============================================================================
/// Trait canonical for the Charon-custom fee matrix pallet (`pallet-origin-fees`).
///
/// Implements the canonical two-axis (HardwareTier × AssetQualityTier) fee
/// formula per CHN-8 + Inmutable #16 anti-clasista. Consumed by:
/// - `pallet-balances` `OnChargeTransaction` (gas fees per extrinsic)
/// - `pallet-marketplace` (91/9% split with tier-aware base)
/// - `pallet-seeds-hosting` (0.6 OGC/world/month canonical)
/// - `pallet-ons-registry` (name registration tier-aware)
pub trait OriginFees {
/// Compute the OGC fee for an extrinsic, given the actor's tier metadata
/// recorded on-chain (`pallet-origin-provenance` tier_assertion entry).
fn fee_for_extrinsic(
&self,
op: OperationKind,
actor: &AccountId,
) -> Result<Ogc, ChainError>;
/// Override fee computation with explicit tier inputs (for off-chain
/// dry-run estimation via RPC). Pure function — no storage reads.
fn estimate_fee(
&self,
op: OperationKind,
hw: HardwareTier,
quality: AssetQualityTier,
) -> Ogc;
/// Burn fraction applied to the fee per CHN-8 + CHN-2 burn matrix.
/// Returns the basis points (0-10000) of the fee to be burned.
fn burn_basis_points(&self, op: OperationKind) -> u16;
}
// ============================================================================
// pallet-origin-validator-economy — CHN-3 NPoS rewards + slashing
// ============================================================================
/// Slashing reason codes per CHN-3 canonical validator economy.
#[derive(
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize,
)]
pub enum SlashReason {
/// Validator was offline beyond the canonical threshold (0.1% downtime
/// per epoch). Partial slash.
Downtime,
/// Validator double-signed a block. Total slash + permanent removal.
DoubleSign,
/// Validator equivocation in GRANDPA voting. Major slash.
Equivocation,
/// Validator misreported tier metadata for fee discount fraud. Partial
/// slash per CHN-8 + Inmutable #16 enforcement.
TierFraud,
}
/// Trait canonical for the Charon-custom validator economy pallet
/// (`pallet-origin-validator-economy`).
///
/// Implements NPoS reward distribution + slashing per CHN-3. Consumed by:
/// - `pallet-session` (validator rotation 4h epochs, CHN-1)
/// - `pallet-staking` (nominator delegation, validator commission)
/// - `pallet-im-online` (downtime detection feed)
/// - `pallet-grandpa` (equivocation feed)
pub trait OriginValidatorEconomy {
/// Distribute block rewards to validators of the current epoch per the
/// 40% Ecosystem Pool canonical curve (10-15yr distribution). Rewards
/// scale with hardware tier per Inmutable #16 (Pi 5 validators NOT
/// disadvantaged versus Ultra hardware).
fn distribute_rewards(&self, epoch: u32) -> Result<Ogc, ChainError>;
/// Apply a slash to a validator. Partial or total stake burn depending
/// on `reason`. Returns the amount burned.
fn slash_validator(
&self,
validator: &AccountId,
reason: SlashReason,
) -> Result<Ogc, ChainError>;
/// Read the canonical commission rate a validator has set for nominators.
/// In basis points (0-10000 = 0%-100%). Validators MAY change commission
/// at the start of each epoch but NOT mid-epoch.
fn validator_commission_bps(&self, validator: &AccountId) -> u16;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn slash_reason_serde_canonical() {
for reason in [
SlashReason::Downtime,
SlashReason::DoubleSign,
SlashReason::Equivocation,
SlashReason::TierFraud,
] {
let json = serde_json::to_string(&reason).unwrap();
let parsed: SlashReason = serde_json::from_str(&json).unwrap();
assert_eq!(reason, parsed);
}
}
#[test]
fn slash_reasons_are_distinct() {
assert_ne!(SlashReason::Downtime, SlashReason::DoubleSign);
assert_ne!(SlashReason::DoubleSign, SlashReason::Equivocation);
assert_ne!(SlashReason::Equivocation, SlashReason::TierFraud);
}
#[test]
fn tier_fraud_is_a_slash_reason_per_inmutable_16() {
// Inmutable #16 anti-clasista enforcement: misreporting tier to dodge
// fees is a slashable offence.
let reason = SlashReason::TierFraud;
let json = serde_json::to_string(&reason).unwrap();
assert_eq!(json, "\"TierFraud\"");
}
}