JoshOrndorff / recipes

A Hands-On Cookbook for Aspiring Blockchain Chefs
GNU General Public License v3.0
378 stars 186 forks source link

polkadot-js/app explorer event display issue #304

Closed chaosma closed 4 years ago

chaosma commented 4 years ago

I added a new pallet and inserted that pallet into the super-runtime. The pallet is very simple, it contains two functions, one is to add a record to the blockchain, the other is to remove a record. When I tested the two functions, it works. But the explorer (extrinsic tab) will keep the notification on the explorer; also the block detail tab not showing the event finish. Here are the screenshots:

add_remove_record

block_detail

I added debug information as well as add/remove the same record to make sure the functions work well. I suspect it's some other issue not related to the pallet I added. Here is the code:

#![cfg_attr(not(feature = "std"), no_std)]

//! proof-of-existence
use frame_support::traits::{Currency, ReservableCurrency, Vec};
use frame_support::{
    debug, decl_error, decl_event, decl_module, decl_storage, dispatch::DispatchResult, ensure,
    storage::StorageMap,
};
use frame_system::{self as system, ensure_signed};
use pallet_timestamp as timestamp;

const POE_FEE: u32 = 66;

pub type BalanceOf<T> =
    <<T as Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::Balance;

pub trait Trait: timestamp::Trait {
    type Currency: Currency<Self::AccountId> + ReservableCurrency<Self::AccountId>;
    type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
}

decl_error! {
    pub enum Error for Module<T: Trait> {
        DigestAlreadyClaimed,
        DigestNotClaimed,
        OwnerMismatch,
    }
}

decl_storage! {
    trait Store for Module<T: Trait> as POEStorage {
        Proof get(fn get_proof): map hasher(identity) Vec<u8> => (T::AccountId, T::Moment);
    }
}

decl_event! {
    pub enum Event<T>
    where
        AccountId = <T as system::Trait>::AccountId,
        Timestamp = <T as timestamp::Trait>::Moment,
    {
        /// Added a proof
        ProofCreated(AccountId,Timestamp,Vec<u8>),
        /// Removed a proof
        ProofRemoved(AccountId,Timestamp,Vec<u8>),
    }
}

decl_module! {
    pub struct Module<T: Trait> for enum Call where origin: T::Origin {
         fn deposit_event() = default;

         #[weight = 10_000]
         pub fn add_proof(origin, digest: Vec<u8>) -> DispatchResult {
             debug::info!("calling add_proof");
             let user = ensure_signed(origin)?;
             debug::info!("Request sent by: {:?}", user);
             ensure!(!<Proof<T>>::contains_key(&digest), <Error<T>>::DigestAlreadyClaimed);
             debug::info!("finish ensure contains_key");
            T::Currency::reserve(&user,BalanceOf::<T>::from(POE_FEE))?;
             debug::info!("finish reserve balance: {:?}", BalanceOf::<T>::from(POE_FEE));
             let time = <timestamp::Module<T>>::now();
             <Proof<T>>::insert(&digest,(user.clone(),time.clone()));
             debug::info!("finish insert at time: {:?}", time.clone());
             Self::deposit_event(RawEvent::ProofCreated(user,time, digest));
             debug::info!("finish deposit event");
             Ok(())
         }

         #[weight = 10_000]
         pub fn remove_proof(origin, digest: Vec<u8>) -> DispatchResult {
             let user = ensure_signed(origin)?;
             ensure!(<Proof<T>>::contains_key(&digest), <Error<T>>::DigestNotClaimed);
             let (owner, _time) = Self::get_proof(&digest);
            ensure!(user==owner,<Error<T>>::OwnerMismatch);
            <Proof<T>>::remove(&digest);
            T::Currency::unreserve(&user, BalanceOf::<T>::from(POE_FEE));
             let time = <timestamp::Module<T>>::now();
             Self::deposit_event(RawEvent::ProofRemoved(user, time, digest));
             Ok(())
         }

    }
}
JoshOrndorff commented 4 years ago

Hello @chaosma. Thanks for using the recipes!

The issue is because of your decl_event!{...} block, and specifically because of the line Timestamp = <T as timestamp::Trait>::Moment.

Because you've made this type alias, you need to tell Polkadot-js Apps about it as well. Go back to the Apps UI and to the Settings -> Developer tab. You will need to add all off the usual super-runtime types (from recipes/runtimes/super-runtime/types.json) as well as this new one "Timestamp": "Moment".

So the complete set of types you need is:

{
  "Address": "AccountId",
  "LookupSource": "AccountId",
  "ContinuousAccountData": {
    "principal": "u64",
    "deposit_date": "BlockNumber"
  },
  "U16F16": "[u8; 4]",
  "GroupIndex": "u32",
  "TaskId": "Vec<u8>",
  "PriorityScore": "u32",
  "RoundIndex": "u32",
  "Task": {
    "id": "TaskId",
    "score": "PriorityScore",
    "proposed_at": "BlockNumber"
  },
  "ValueStruct": {
    "integer": "i32",
    "boolean": "bool"
  },
  "BufferIndex": "u8",
  "AccountIdOf": "AccountId",
  "BalanceOf": "Balance",
  "FundInfoOf": "FundInfo",
  "FundInfo": {
    "beneficiary": "AccountId",
    "deposit": "Balance",
    "raised": "Balance",
    "end": "BlockNumber",
    "goal": "Balance"
  },
  "FundIndex": "u32",
  "InnerThing": {
    "number": "u32",
    "hash": "Hash",
    "balance": "Balance"
  },
  "SuperThing": {
    "super_number": "u32",
    "inner_thing": "InnerThing"
  },
  "InnerThingOf": "InnerThing",
  "Timestamp": "Moment"
}
chaosma commented 4 years ago

@JoshOrndorff Cool! It works now. Thanks for your quick answer.