From c2357d7ac012e638a4498c9727242fc9984fa412 Mon Sep 17 00:00:00 2001 From: Michael Eberhardt Date: Thu, 28 Mar 2024 11:22:30 +0100 Subject: [PATCH] feat: implement rpc functionality within the pallet --- pallet/src/api.rs | 4 +- pallet/src/lib.rs | 95 +++++++++++++++++++++++++++++++++++++++++++++++ rpc/src/lib.rs | 12 +++--- 3 files changed, 103 insertions(+), 8 deletions(-) diff --git a/pallet/src/api.rs b/pallet/src/api.rs index a60b592..72f2d86 100644 --- a/pallet/src/api.rs +++ b/pallet/src/api.rs @@ -40,10 +40,10 @@ sp_api::decl_runtime_apis! { fn estimate_gas_execute_script(transaction: Vec) -> Result; // Get module binary by its address. - fn get_module(address: String, name: String) -> Result>, Vec>; + fn get_module(address: AccountId, name: String) -> Result>, Vec>; // Get module ABI by its address. - fn get_module_abi(address: String, name: String) -> Result, Vec>; + fn get_module_abi(address: AccountId, name: String) -> Result, Vec>; // Get resource. fn get_resource(account: AccountId, tag: Vec) -> Result>, Vec>; diff --git a/pallet/src/lib.rs b/pallet/src/lib.rs index e10845c..985be9a 100644 --- a/pallet/src/lib.rs +++ b/pallet/src/lib.rs @@ -64,6 +64,7 @@ pub mod pallet { use super::*; use crate::{ + api::MoveApiEstimation, balance::{BalanceAdapter, BalanceOf}, signer::*, storage::{MoveVmStorage, StorageAdapter}, @@ -629,6 +630,100 @@ pub mod pallet { } } + // RPC method implementation for simple node integration. + impl Pallet { + pub fn rpc_gas_to_weight(_gas_limit: u64) -> Weight { + // TODO (eiger): implement in M3 + Weight::from_parts(1_123_123, 0) // Hardcoded for testing + } + + pub fn rpc_weight_to_gas(_weight: Weight) -> u64 { + // TODO (eiger): implement in M3 + 100 + } + + pub fn rpc_estimate_gas_publish_module( + account: &T::AccountId, + bytecode: Vec, + ) -> Result { + let address = Self::to_move_address(account)?; + let vm_result = Self::raw_publish_module(&address, bytecode, GasStrategy::DryRun)?; + + Ok(MoveApiEstimation { + vm_status_code: vm_result.status_code.into(), + gas_used: vm_result.gas_used, + }) + } + + pub fn rpc_estimate_gas_publish_bundle( + account: &T::AccountId, + bytecode: Vec, + ) -> Result { + let address = Self::to_move_address(account)?; + let vm_result = Self::raw_publish_bundle(&address, bytecode, GasStrategy::DryRun)?; + + Ok(MoveApiEstimation { + vm_status_code: vm_result.status_code.into(), + gas_used: vm_result.gas_used, + }) + } + + pub fn rpc_estimate_gas_execute_script( + transaction_bc: Vec, + ) -> Result { + // Main input for the VM are these script parameters. + let ScriptTransaction { + bytecode, + args, + type_args, + } = ScriptTransaction::try_from(transaction_bc.as_ref()) + .map_err(|_| Error::::InvalidScriptTransaction)?; + let args: Vec<&[u8]> = args.iter().map(AsRef::as_ref).collect(); + + // Make sure the script parameters are valid. + let signer_count = + verify_script_integrity_and_check_signers(&bytecode).map_err(Error::::from)?; + + // In the case of a dry run, we have an "unlimited" balance (u128::MAX) because it is + // not relevant to the gas estimation (no changes will be applied). + let unlimited_balance = BalanceAdapter::::for_dry_run(&args, signer_count)?; + + let vm_result = Self::raw_execute_script( + &bytecode, + type_args, + args, + GasStrategy::DryRun, + unlimited_balance, + )?; + + Ok(MoveApiEstimation { + vm_status_code: vm_result.status_code.into(), + gas_used: vm_result.gas_used, + }) + } + + pub fn rpc_get_module( + account: T::AccountId, + name: String, + ) -> Result>, Vec> { + Self::get_module(&account, &name) + } + + pub fn rpc_get_module_abi( + account: T::AccountId, + name: String, + ) -> Result, Vec> { + Self::get_module_abi(&account, &name) + } + + pub fn rpc_get_resource( + account: T::AccountId, + tag: Vec, + ) -> Result>, Vec> { + Self::get_resource(&account, tag.as_slice()) + } + } + #[pallet::error] pub enum Error { // General errors diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 45e1f94..a9be66d 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -81,7 +81,7 @@ pub trait MoveApi { #[method(name = "mvm_getModuleABI")] fn get_module_abi( &self, - address: &str, + address: AccountId, name: &str, at: Option, ) -> RpcResult>; @@ -90,7 +90,7 @@ pub trait MoveApi { #[method(name = "mvm_getModule")] fn get_module( &self, - address: &str, + address: AccountId, name: &str, at: Option, ) -> RpcResult>>; @@ -210,14 +210,14 @@ where fn get_module_abi( &self, - address: &str, + address: AccountId, name: &str, at: Option<::Hash>, ) -> RpcResult> { let api = self.client.runtime_api(); let res = api.get_module_abi( at.unwrap_or_else(|| self.client.info().best_hash), - address.to_string(), + address, name.to_string(), ); @@ -227,14 +227,14 @@ where fn get_module( &self, - address: &str, + address: AccountId, name: &str, at: Option<::Hash>, ) -> RpcResult>> { let api = self.client.runtime_api(); let res = api.get_module( at.unwrap_or_else(|| self.client.info().best_hash), - address.to_string(), + address, name.to_string(), );