Using Timestamp in substrate runtime: set_timestamp not found - substrate

I am trying to fast forward time to do some tests for a custom runtime module. I have looked at the answer from this thread and followed the answer to use Timestamp, however, I am unable to access the set_timestamp method.
setup:
#[cfg(test)]
mod tests {
use super::*;
use support::dispatch::Vec;
use runtime_primitives::traits::{Hash};
use runtime_io::with_externalities;
use primitives::{H256, Blake2Hasher};
use timestamp;
use support::{impl_outer_origin, assert_ok, assert_noop};
use runtime_primitives::{
BuildStorage,
traits::{BlakeTwo256, IdentityLookup},
testing::{Digest, DigestItem, Header}
};
impl_outer_origin! {
pub enum Origin for Test {}
}
#[derive(Clone, Eq, PartialEq)]
pub struct Test;
impl system::Trait for Test {
type Origin = Origin;
type Index = u64;
type BlockNumber = u64;
type Hash = H256;
type Hashing = BlakeTwo256;
type Digest = Digest;
type AccountId = u64;
type Lookup = IdentityLookup<Self::AccountId>;
type Header = Header;
type Event = ();
type Log = DigestItem;
}
impl super::Trait for Test {
type Event = ();
}
impl timestamp::Trait for Test {
type Moment = u64;
type OnTimestampSet = ();
}
type Pizza = Module<Test>;
And the error is below:
error[E0599]: no function or associated item named `set_timestamp` found for type
`srml_timestamp::Module<tests::Test>` in the current scope
|
254 | let now = <timestamp::Module<tests::Test>>::set_timestamp(9);
| ^^^^^^^^^^^^^ function or associated item
not found in `srml_timestamp::Module<tests::Test>`

In Substrate v1.0, the set_timestamp function has a #[cfg(feature = "std")] attribute on it:
https://github.com/paritytech/substrate/blob/v1.0/srml/timestamp/src/lib.rs#L276
This means it will only be visible if you are compiling with std. When you write tests, this should work, but I assume that this issue is appearing because you are trying to call it from within the runtime environment, which much be no_std.
If for some reason you do need to modify the timestamp from within your runtime, you should be able to do so directly:
https://github.com/paritytech/substrate/blob/v1.0/srml/timestamp/src/lib.rs#L249
<timestamp::Module<T>>::Now::put(new_time)
(I haven't tested this, but something like it should work).
Let me know if this helps.

In Substrate v1.0 you can declare
type Moment = timestamp::Module<Test>;
Then use it to set a specific timestamp.
Moment::set_timestamp(9);
If you want to get the timestamp value, you can do:
let now_timestamp = Moment::now();

Related

What should I put into FindAppointmentsAsync's &self parameter?

I'm new to rust and am trying to make use of the windows cargo. But I don't understand what I should set the &self parameter in the FindAppointmentsAsync function.
This is Cargo.toml:
[package]
name = "rust-test"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[dependencies.windows]
version = "0.43.0"
features = [
"ApplicationModel",
"ApplicationModel_Appointments",
"Foundation_Collections",
]
This is main.rs:
use std::time::Duration;
use windows::{
core::*, ApplicationModel::Appointments::*, Foundation::{DateTime, TimeSpan},
};
fn main() -> Result<()> {
let rangestart = DateTime::default();
let rangelength = TimeSpan::from(Duration::new(60 * 60 * 24 * 30, 0));
println!("test");
unsafe {
let store = AppointmentStore();
let result = AppointmentStore::FindAppointmentsAsync(&store, rangestart, rangelength);
}
Ok(())
}
If let store = AppointmentStore::new(); the error is no function or associated item named 'new' found
If let store = AppointmentStore();, the error is expected 1 argument, found 0
If let store = AppointmentStore(""); the error is cannot initialize a tuple struct which contains private fields
You cannot create an AppointmentStore directly, as it has private fields and does not expose a constructor function.
Looking at the docs, there are two ways to get an AppointmentStore:
By calling clone on an existing one.
By calling RequestStoreAsync on an AppointmentManager or AppointmentManagerForUser.
AppointmentManager is a struct with no fields, so you can create one by simply doing:
let foo = AppointmentManager;
let bar = foo.RequestStoreAsync(/* insert params here */);
AppointmentManagerForUser also cannot be constructed directly, and is obtained by calling GetForUser on an AppointmentManager.

How can I print the code that is built at runtime by construct_runtime?

I cloned the substrate repository. In bin/node-template/runtime/src/lib.rs, construct_runtime! is called to create the runtime. I found the definition of construct_runtime in frame/support/procedural/src/construct_runtime/mod.rs. It calls construct_runtime_parsed which builds a block of code during runtime.
let res = quote!(
#scrate_decl
#[derive(Clone, Copy, PartialEq, Eq, #scrate::sp_runtime::RuntimeDebug)]
pub struct #name;
impl #scrate::sp_runtime::traits::GetNodeBlockType for #name {
type NodeBlock = #node_block;
}
impl #scrate::sp_runtime::traits::GetRuntimeBlockType for #name {
type RuntimeBlock = #block;
}
#outer_event
#outer_origin
#all_modules
#module_to_index
#dispatch
#metadata
#outer_config
#inherent
#validate_unsigned
#integrity_test
);
Are there any ways that I can print or check the code passed to quote! that is built by construct_runtime_parsed?
You can point cargo expand at the runtime/src/lib.rs file and it will output the expanded source code.

How do I store a Random number generator in a struct?

I am trying to store a Random number generator in a struct. I can't seem to get the struct definition for any Rng structs to be recognized, like ThreadRng. This works:
use rand::{
self,
distributions::{Distribution, Uniform},
}; // 0.6.4
fn main() {
let mut rng = rand::thread_rng();
let die_range = Uniform::new_inclusive(1, 6);
let die = die_range.sample(&mut rng);
println!("{}", die);
}
However, if I try to define a variable to have the actual type of the Rng, I get an error:
use rand::{
self,
ThreadRng,
distributions::{Distribution, Uniform},
}; // 0.6.4
fn main() {
let mut rng :ThreadRng = rand::thread_rng();
let die_range = Uniform::new_inclusive(1, 6);
let die = die_range.sample(&mut rng);
println!("{}", die);
}
The error is:
error[E0432]: unresolved import `rand::ThreadRng`
--> src/main.rs:3:5
|
3 | ThreadRng,
| ^^^^^^^^^
| |
| no `ThreadRng` in the root
| help: a similar name exists in the module: `thread_rng`
I want to store the Rng in a struct, and I do not want a trait object. How do I import the definition of ThreadRng? Or XorShiftRng (which might be faster - I do not need cryptographic strength)? Is the type in some sub-module I don't know about? All the examples I read online call a method to get the Rng and use it locally; they never store it in a struct and never define any variables that use the struct name.
If you look at the documentation rand::thread_rng, you can click on its return type to see that its fully qualified name is actually rand::rngs::ThreadRng.

Unable to send a &str between threads because it does not live long enough

Given the following simplified program:
#[macro_use] extern crate log;
extern crate ansi_term;
extern crate fern;
extern crate time;
extern crate threadpool;
extern crate id3;
mod logging;
use std::process::{exit, };
use ansi_term::Colour::{Yellow, Green};
use threadpool::ThreadPool;
use std::sync::mpsc::channel;
use std::path::{Path};
use id3::Tag;
fn main() {
logging::setup_logging();
let n_jobs = 2;
let files = vec!(
"/tmp/The Dynamics - Version Excursions/01-13- Move on Up.mp3",
"/tmp/The Dynamics - Version Excursions/01-09- Whole Lotta Love.mp3",
"/tmp/The Dynamics - Version Excursions/01-10- Feel Like Making Love.mp3"
);
let pool = ThreadPool::new(n_jobs);
let (tx, rx) = channel();
let mut counter = 0;
for file_ in files {
let file_ = Path::new(file_);
counter = counter + 1;
let tx = tx.clone();
pool.execute(move || {
debug!("sending {} from thread", Yellow.paint(counter.to_string()));
let tag = Tag::read_from_path(file_).unwrap();
let a_name = tag.artist().unwrap();
debug!("recursed file from: {} {}",
Green.paint(a_name), file_.display());
tx.send(".").unwrap();
// TODO amb: not working..
// tx.send(a_name).unwrap();
});
}
for value in rx.iter().take(counter) {
debug!("receiving {} from thread", Green.paint(value));
}
exit(0);
}
Everything works as expected, unless the one commented line (tx.send(a_name).unwrap();) is put back in. In that case I get the following error:
error: `tag` does not live long enough
let a_name = tag.artist().unwrap();
^~~
note: reference must be valid for the static lifetime...
note: ...but borrowed value is only valid for the block suffix following statement 1 at 39:58
let tag = Tag::read_from_path(file_).unwrap();
let a_name = tag.artist().unwrap();
debug!("recursed file from: {} {}",
Green.paint(a_name), file_.display());
...
Generally I understand what the compiler tells me, but I don't see a problem since the variable tag is defined inside of the closure block. The only problem that I can guess is, that the variable tx is cloned outside and therefore can collide with the lifetime of tag.
My goal is to put all the current logic in the thread-closure inside of the thread, since this is the "processing" I want to spread to multiple threads. How can I accomplish this, but still send some value to the longer existing tx?
I'm using the following Rust version:
$ rustc --version
rustc 1.9.0 (e4e8b6668 2016-05-18)
$ cargo --version
cargo 0.10.0-nightly (10ddd7d 2016-04-08)
a_name is &str borrowed from tag. Its lifetime is therefore bounded by tag. Sending non 'static references down a channel to another thread is unsafe. It refers to something on the threads stack which might not even exist anymore once the receiver tries to access it.
In your case you should promote a_name to an owned value of type String, which will be moved to the receiver thread.
tx.send(a_name.to_owned()).unwrap();

Unable to type alias a specialised generic enum

Given the following:
use std::fmt::Debug;
#[derive(Debug)]
enum A<T: Debug> {
X,
Y(T),
}
#[derive(Debug)]
struct B;
type C = A<B>;
// use A<B> as C; // Does not compile
I can use it as:
fn main() {
let val0 = A::X::<B>;
let val1 = A::Y::<B>(B);
println!("{:?}\t{:?}", val0, val1);
}
But then for more than one generic parameter (or if A, B etc were much longer names then to alias it I tried the following but it doesn't compile:
fn main() {
let val0 = C::X;
let val1 = C::Y(B);
println!("{:?}\t{:?}", val0, val1);
}
with errors:
src/main.rs:656:16: 656:20 error: no associated item named `X` found for type `A<B>` in the current scope
src/main.rs:656 let val0 = C::X;
^~~~
src/main.rs:657:16: 657:20 error: no associated item named `Y` found for type `A<B>` in the current scope
src/main.rs:657 let val1 = C::Y(B);
As also noted i am unable to use use to solve the problem. Is there a way around it (because typing the whole thing seems to be cumbersome) ?
rustc --version
rustc 1.9.0 (e4e8b6668 2016-05-18)
Is there a way around it (because typing the whole thing seems to be cumbersome)?
You can specify C as the type of the variable so you can use A::X or A::Y without explicit specifying the type parameter:
let val0: C = A::X;
let val1: C = A::Y(B);

Resources