Skip to content

Latest commit

 

History

History
142 lines (116 loc) · 4.07 KB

8.8调试.md

File metadata and controls

142 lines (116 loc) · 4.07 KB

开发pallet时的调试

今天我们来讲讲在开发pallet的时候如何调试。在pallet开发时主要有以下几种调试方式:

  • logging uilities;
  • printable trait;
  • print函数;
  • if_std.

下面我们来一一演示。

1 准备

首先我们进入到substrate-node-template/pallets目录下,拷贝template然后命名为Debug,然后修改包名为pallet-debug。然后修改runtime中的内容将pallet-debug加载到runtime中。对于这几步不会的可以看我们前面的讲解,基本上我们每新加一个pallet都会使用这步。

接下来就是在pallet-debug中进行修改。

2 使用logging uilities

这种方式就是使用log包进行打印,需要在pallet-debug的Cargo.toml中添加依赖如下:

[dependencies]
...
log = { version = "0.4.14", default-features = false }
...

[features]
default = ["std"]
std = [
	...
	"log/std",
	"sp-runtime/std",
	"sp-std/std",
]

然后我们可以在lib.rs的代码中使用log进行打印,如下:

	pub fn do_something(origin: OriginFor<T>, something: u32) -> DispatchResult {
			let who = ensure_signed(origin)?;
			<Something<T>>::put(something);
			log::info!("|||||||||||||||||||||| called by {:?}", who);
			
			Self::deposit_event(Event::SomethingStored(something, who));
			Ok(())
		}

3 使用printable trait

此种方式我们需要为需要打印的类型实现printable trait,在我们的示例中我们主要为Error类型实现对应的trait,然后再进行打印,需要修改代码如下:

use sp_runtime::traits::Printable;
use sp_runtime::print;
...

	#[pallet::error]
	pub enum Error<T> {
		NoneValue,
		StorageOverflow,
	}

	impl<T: Config> Printable for Error<T> {
        fn print(&self) {
            match self {
                Error::NoneValue => "Invalid Value".print(),
                Error::StorageOverflow => "++++++++++++++++++++++++++ Value Exceeded and Overflowed".print(),
                _ => "Invalid Error Case".print(),
            }
        }
    }
    
   ...
   
   	#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
		pub fn cause_error(origin: OriginFor<T>) -> DispatchResult {
			log::info!("|||||||||||||||||||||| cause error");
			let _who = ensure_signed(origin)?;
			match <Something<T>>::get() {
				None => { 
                                        //下面一行打印对应的错误
					print(Error::<T>::NoneValue);
					Err(Error::<T>::NoneValue)? 
				},
				Some(old) => {
					log::info!("|||||||||||||||||||||| 2 error");
					let new = old.checked_add(1).ok_or({
                                                //下面一行打印对应的错误
						print(Error::<T>::StorageOverflow);  
						Error::<T>::StorageOverflow
					})?;
					<Something<T>>::put(new);
					Ok(())
				},
			}
		}

4 使用print函数

此处直接使用print进行打印,不过使用前也需要引入use sp_runtime::print;

打印的示例代码如下:

		#[pallet::weight(10_000 + T::DbWeight::get().writes(1))]
		pub fn do_something(origin: OriginFor<T>, something: u32) -> DispatchResult {
			let who = ensure_signed(origin)?;
			<Something<T>>::put(something);
			//示例代码
			print("After storing my_val");
			Self::deposit_event(Event::SomethingStored(something, who));
			Ok(())
		}

5 使用 if_std

此种方式我本地没有实验成功,有兴趣的小伙伴可以研究研究。示例代码如下:

	use sp_std::if_std;
	...
	
	#[pallet::weight(10_000 + T::DbWeight::get().writes(1))]
	pub fn do_something(origin: OriginFor<T>, something: u32) -> DispatchResult {
		let who = ensure_signed(origin)?;
		<Something<T>>::put(something);

		if_std! {
                	println!("Hello native world!");
                        println!("My value is: {:#?}", something);
                	println!("The caller account is: {:#?}", who);
            	}

		Self::deposit_event(Event::SomethingStored(something, who));
		Ok(())
	}

6 参考文档

https://docs.substrate.io/v3/runtime/debugging/

7 完整源码地址

https://github.com/anonymousGiga/learn-substrate-easy-source/blob/main/substrate-node-template/pallets/debug/src/lib.rs