feat(revive): v0.0.37 — pallet-revive workspace scaffold + ChainAction Phase 3 extension 🎉
Phase 3 Slice 3.1 Ship 1 SCAFFOLD shipped. Path A inicio post sesión 3+
extended histórica (35 ships v0.0.1→v0.0.36 + Slice 2e WASM RESUELTO). David
autorizó "vamos con todas en orden desde A" — pallet-revive smart contracts
PolkaVM RISC-V + ink! v6 + Solidity per SBS-5 ratificado (supersedes CHN-6 v1.0).
Cambios:
- Cargo.toml workspace.dependencies: pallet-revive 0.12.2 + pallet-revive-uapi 0.13.0
Version pin canonical para stable2512-3 verificado vía
github.com/paritytech/polkadot-sdk/blob/polkadot-stable2512-3/substrate/frame/revive/Cargo.toml
(latest 0.17.0 requiere bump Substrate generation — scope Phase 8+).
- crates/origin-chain-types/src/actions.rs: ChainAction enum extension OCAFB-2
semver-respecting con 3 nuevas variants ordinals 4/5/6:
* DeployContract (pallet-revive::instantiate)
* CallContract (pallet-revive::call)
* UploadContractCode (pallet-revive::upload_code sin instantiate)
Ordinals 0-3 {Read/Write/Compute/Transfer} preservados intactos. Wire format
stable canonical — name() snake_case + ordinal() u8 + from_ordinal() forward-compat
+ serde + scale-codec roundtrip todos actualizados. +1 test
chain_action_phase_3_variants_distinct_from_legacy.
- crates/origin-chain-fees/src/fee_schedule.rs: subsidy_basis_points + entitlement_unlocked
matches updated exhaustivamente para 3 nuevas variants. Mapping interim conservador
(DeployContract/UploadContractCode ~= Write semantics, CallContract ~= Compute).
Refinement Phase 3.2 con Mathi OitFeeSchedule extension post-OCAFB ratify +
measurements empíricos gas/deposit reales.
Verificación:
- cargo check --workspace clean (0 errors, warnings pre-existentes)
- cargo test --workspace: 203 tests verde (baseline 202 + 1 new test) 0 failures
- ChainAction actions::tests 7/7 verde (4 originales updated + 3 nuevos covered)
Próximo Ship 2 v0.0.38: pallet-revive wired runtime Index 11 (27 Config types
associated types + parameter_types canonical Asset Hub Westend reference).
⚓ Path A Phase 3 kickoff. La nave continúa zarpando.
🤖 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
199636ac05
commit
ec5b5bd2b2
3 files changed
+127
-20
No files matched your search
@@ -99,6 +99,24 @@ pub const fn subsidy_basis_points(hw: HardwareTier, action: ChainAction) -> u32
|
||||
(Ultra, Write) => 0,
|
||||
(Ultra, Compute) => 0,
|
||||
(Ultra, Transfer) => 0,
|
||||
// Phase 3 SBS-5 contract actions — anti-clasista mapping interim
|
||||
// (Slice 3.1 SCAFFOLD v0.0.37). Mappeo conservativo análogo a Write
|
||||
// (DeployContract + UploadContractCode = storage-heavy) y Compute
|
||||
// (CallContract = PolkaVM gas execution). Refinement Slice 3.2 cuando
|
||||
// Mathi extiende OitFeeSchedule con measurements empíricos gas/deposit
|
||||
// reales post-Phase 3 Ship 2 wired runtime Index 11.
|
||||
(EmbeddedArm, DeployContract) => 9000, // Pi 5 dev contracts canonical
|
||||
(EmbeddedArm, CallContract) => 10000, // educational call free
|
||||
(EmbeddedArm, UploadContractCode) => 9000, // Pi 5 storage subsidy
|
||||
(Portable, DeployContract) => 7500,
|
||||
(Portable, CallContract) => 5000,
|
||||
(Portable, UploadContractCode) => 7500,
|
||||
(Desktop, DeployContract) => 2500,
|
||||
(Desktop, CallContract) => 2500,
|
||||
(Desktop, UploadContractCode) => 2500,
|
||||
(Ultra, DeployContract) => 0,
|
||||
(Ultra, CallContract) => 0,
|
||||
(Ultra, UploadContractCode) => 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +138,18 @@ pub const fn entitlement_unlocked(tier: SubscriptionTier, action: ChainAction) -
|
||||
(Pro, Write) => true,
|
||||
(Pro, Compute) => true, // basic compute unlocked
|
||||
(Pro, Transfer) => true,
|
||||
// Ultra: ALL incluyendo EEG Compute (Inmutable #18)
|
||||
// Phase 3 SBS-5 contract actions Free tier — conservativo interim
|
||||
// (Slice 3.1 SCAFFOLD v0.0.37). Free user blocked de smart contract
|
||||
// operations por default. Refinement Slice 3.2 con Mathi: educational
|
||||
// world override + Pi 5 dev path canonical via subscription upgrade
|
||||
// gratuita post-OCAFB ratify Phase 3 maduración.
|
||||
(Free, DeployContract) => false, // requires Pro+ initial
|
||||
(Free, CallContract) => false, // requires Pro+ initial
|
||||
(Free, UploadContractCode) => false, // requires Pro+ initial
|
||||
(Pro, DeployContract) => true,
|
||||
(Pro, CallContract) => true,
|
||||
(Pro, UploadContractCode) => true,
|
||||
// Ultra: ALL incluyendo EEG Compute (Inmutable #18) y contracts
|
||||
(Ultra, _) => true,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,17 @@
|
||||
//! análogo DCM-4 `default_material()` Marihan + `HardwareTier` mirror Phanes
|
||||
//! `arkhe-asset::manifest_validator`).
|
||||
//!
|
||||
//! 4 variants canonical {Read, Write, Compute, Transfer} con ordinals 0/1/2/3
|
||||
//! stable wire format — adding variants future appende al final preservando
|
||||
//! ordinals existentes (semver respect canonical).
|
||||
//! 7 variants canonical {Read, Write, Compute, Transfer, DeployContract,
|
||||
//! CallContract, UploadContractCode} con ordinals 0..=6 stable wire format —
|
||||
//! adding variants future appende al final preservando ordinals existentes
|
||||
//! (semver respect canonical).
|
||||
//!
|
||||
//! **Phase 3 SBS-5 ratified extension (2026-05-27, Slice 3.1 Ship 1 v0.0.37)**:
|
||||
//! variants 4/5/6 añadidas para `pallet-revive` smart contract operations
|
||||
//! (PolkaVM RISC-V + ink! v6 + Solidity). Permiten fee differentiation futura
|
||||
//! por Mathi `OitFeeSchedule` post-OCAFB ratify — `DeployContract` gas-heavy
|
||||
//! (storage deposit + bytecode upload), `CallContract` execution-metered,
|
||||
//! `UploadContractCode` storage-only (sin instantiate).
|
||||
//!
|
||||
//! Bidirectional conversion canonical wire-compat via `From<u8>` + serde
|
||||
//! `rename_all="snake_case"` + scale-codec derives canonical.
|
||||
@@ -45,6 +53,20 @@ pub enum ChainAction {
|
||||
/// Transfer OGC token (peer-to-peer, fee redirect, governance staking).
|
||||
/// Free user limitado a basic ≤10 OGC/day per OCAFB-4 entitlement.
|
||||
Transfer,
|
||||
/// Deploy smart contract via `pallet-revive::instantiate` (Phase 3 SBS-5).
|
||||
/// Carga code hash + storage deposit + instantiate constructor. Fee
|
||||
/// modulado por storage deposit (DepositPerByte + DepositPerItem) + gas
|
||||
/// metering PolkaVM execution.
|
||||
DeployContract,
|
||||
/// Invoke smart contract method via `pallet-revive::call` (Phase 3 SBS-5).
|
||||
/// Fee gas-metered en PolkaVM execution + storage write deposits si la
|
||||
/// llamada muta state. Read-only views también incurren minimal gas fee.
|
||||
CallContract,
|
||||
/// Upload PolkaVM bytecode WITHOUT instantiate via `pallet-revive::upload_code`
|
||||
/// (Phase 3 SBS-5). Solo deposita code en storage por su size + lockup
|
||||
/// deposit canonical. Permite separar code authorship de instantiation
|
||||
/// (e.g. template publishing pattern por Sussi Ethos credentials Slice 3.4).
|
||||
UploadContractCode,
|
||||
}
|
||||
|
||||
impl ChainAction {
|
||||
@@ -55,18 +77,25 @@ impl ChainAction {
|
||||
ChainAction::Write => "write",
|
||||
ChainAction::Compute => "compute",
|
||||
ChainAction::Transfer => "transfer",
|
||||
ChainAction::DeployContract => "deploy_contract",
|
||||
ChainAction::CallContract => "call_contract",
|
||||
ChainAction::UploadContractCode => "upload_contract_code",
|
||||
}
|
||||
}
|
||||
|
||||
/// Ordinal canonical para wire format `u8` (cross-crate sin requerir serde).
|
||||
/// `0=Read 1=Write 2=Compute 3=Transfer`. Stable order — adding variants
|
||||
/// future appende al final preservando ordinals existentes (semver respect).
|
||||
/// `0=Read 1=Write 2=Compute 3=Transfer 4=DeployContract 5=CallContract
|
||||
/// 6=UploadContractCode`. Stable order — adding variants future appende al
|
||||
/// final preservando ordinals existentes (semver respect).
|
||||
pub const fn ordinal(self) -> u8 {
|
||||
match self {
|
||||
ChainAction::Read => 0,
|
||||
ChainAction::Write => 1,
|
||||
ChainAction::Compute => 2,
|
||||
ChainAction::Transfer => 3,
|
||||
ChainAction::DeployContract => 4,
|
||||
ChainAction::CallContract => 5,
|
||||
ChainAction::UploadContractCode => 6,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +107,9 @@ impl ChainAction {
|
||||
1 => Some(ChainAction::Write),
|
||||
2 => Some(ChainAction::Compute),
|
||||
3 => Some(ChainAction::Transfer),
|
||||
4 => Some(ChainAction::DeployContract),
|
||||
5 => Some(ChainAction::CallContract),
|
||||
6 => Some(ChainAction::UploadContractCode),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -87,38 +119,58 @@ impl ChainAction {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// All 7 canonical variants para iteración exhaustiva en tests.
|
||||
const ALL_VARIANTS: [ChainAction; 7] = [
|
||||
ChainAction::Read,
|
||||
ChainAction::Write,
|
||||
ChainAction::Compute,
|
||||
ChainAction::Transfer,
|
||||
ChainAction::DeployContract,
|
||||
ChainAction::CallContract,
|
||||
ChainAction::UploadContractCode,
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn chain_action_name_lowercase_canonical() {
|
||||
assert_eq!(ChainAction::Read.name(), "read");
|
||||
assert_eq!(ChainAction::Write.name(), "write");
|
||||
assert_eq!(ChainAction::Compute.name(), "compute");
|
||||
assert_eq!(ChainAction::Transfer.name(), "transfer");
|
||||
assert_eq!(ChainAction::DeployContract.name(), "deploy_contract");
|
||||
assert_eq!(ChainAction::CallContract.name(), "call_contract");
|
||||
assert_eq!(
|
||||
ChainAction::UploadContractCode.name(),
|
||||
"upload_contract_code"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chain_action_ordinal_stable_canonical() {
|
||||
// Ordinals 0-3 preservados canonical (OCAFB-2 wire format estable).
|
||||
assert_eq!(ChainAction::Read.ordinal(), 0);
|
||||
assert_eq!(ChainAction::Write.ordinal(), 1);
|
||||
assert_eq!(ChainAction::Compute.ordinal(), 2);
|
||||
assert_eq!(ChainAction::Transfer.ordinal(), 3);
|
||||
// Phase 3 SBS-5 extension: ordinals 4-6 appended preservando 0-3.
|
||||
assert_eq!(ChainAction::DeployContract.ordinal(), 4);
|
||||
assert_eq!(ChainAction::CallContract.ordinal(), 5);
|
||||
assert_eq!(ChainAction::UploadContractCode.ordinal(), 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chain_action_from_ordinal_roundtrip_canonical() {
|
||||
for action in [
|
||||
ChainAction::Read,
|
||||
ChainAction::Write,
|
||||
ChainAction::Compute,
|
||||
ChainAction::Transfer,
|
||||
] {
|
||||
for action in ALL_VARIANTS {
|
||||
assert_eq!(ChainAction::from_ordinal(action.ordinal()), Some(action));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chain_action_from_ordinal_unknown_returns_none() {
|
||||
// Forward-compat: ordinals futuros NO conocidos retornan None safe
|
||||
assert_eq!(ChainAction::from_ordinal(4), None);
|
||||
// Forward-compat: ordinals futuros NO conocidos retornan None safe.
|
||||
// Ordinal 7+ NO assigned aún (reserved para variants futuras tipo
|
||||
// CrossChainBridge, PrecompileInvoke, etc).
|
||||
assert_eq!(ChainAction::from_ordinal(7), None);
|
||||
assert_eq!(ChainAction::from_ordinal(100), None);
|
||||
assert_eq!(ChainAction::from_ordinal(255), None);
|
||||
}
|
||||
|
||||
@@ -128,19 +180,35 @@ mod tests {
|
||||
assert_eq!(json, "\"read\"");
|
||||
let parsed: ChainAction = serde_json::from_str("\"compute\"").unwrap();
|
||||
assert_eq!(parsed, ChainAction::Compute);
|
||||
// Phase 3 SBS-5 variants también serializan snake_case.
|
||||
assert_eq!(
|
||||
serde_json::to_string(&ChainAction::DeployContract).unwrap(),
|
||||
"\"deploy_contract\""
|
||||
);
|
||||
let parsed_upload: ChainAction =
|
||||
serde_json::from_str("\"upload_contract_code\"").unwrap();
|
||||
assert_eq!(parsed_upload, ChainAction::UploadContractCode);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chain_action_scale_encode_decode_roundtrip_canonical() {
|
||||
for action in [
|
||||
ChainAction::Read,
|
||||
ChainAction::Write,
|
||||
ChainAction::Compute,
|
||||
ChainAction::Transfer,
|
||||
] {
|
||||
for action in ALL_VARIANTS {
|
||||
let encoded = action.encode();
|
||||
let decoded = ChainAction::decode(&mut &encoded[..]).unwrap();
|
||||
assert_eq!(decoded, action);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chain_action_phase_3_variants_distinct_from_legacy() {
|
||||
// Phase 3 contract operations NO se solapan con generic Read/Write/Compute.
|
||||
// Diseñadas para fee differentiation post-Mathi OitFeeSchedule extensión
|
||||
// canonical post-OCAFB ratify Phase 3.x maduración.
|
||||
assert_ne!(ChainAction::DeployContract, ChainAction::Write);
|
||||
assert_ne!(ChainAction::CallContract, ChainAction::Compute);
|
||||
assert_ne!(ChainAction::UploadContractCode, ChainAction::Write);
|
||||
// Pero ChainAction::DeployContract es semánticamente "Write con bytecode" —
|
||||
// Mathi puede mapear DeployContract → Write fee_for_action() base
|
||||
// multiplicado por bytecode size (canonical decision deferred Phase 3.2).
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user