From c23cc3b0b7eac0b7c6569170d4aa8a17aebb990a Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Thu, 8 Feb 2018 21:07:13 +0100 Subject: [PATCH 1/6] update wasm binaries --- .../release/polkadot_runtime.compact.wasm | Bin 77991 -> 77991 bytes .../release/polkadot_runtime.wasm | Bin 78040 -> 78040 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm index 5418e0432c20b6e36fc79ff8ab4f65e793bcc78b..4f3bdfc57d502916d6b2c4bf1dfeac3f3fae2273 100644 GIT binary patch delta 1767 zcmZ`(du&rx7(d^+t-ae_y9*hm(AT-$tAmQe1fomOT{LlzvUMAe2}Ux#!k~s*72|*ig2v4EF5Hu)-OhS}|EheV%xflowg8JRwtX>KDY>@VueIVB;6VQB_h8a=gia~Xm`iM@Iq;d^k*Wk_jFN1ct;Rh-X zdsK^DBhTY|7M}b6x=+A7KCLlGV~Vz}u^wn#;X_OEY^o8hZqL_A_^;1@@9B5S(}|?s zGGLoGE%h02+{=GkJdDBG(2|)JTP&aw*{Y@tnqn6R>Hh$D&19`mGCPo zgEW=)pmH^zGvMMCE0c7@i0NpT#(MVPO@ePKLreg!%De5qQ)hbMsATVH4BaX}UL^hD6|Ue7WL75v`zlcP+6!6X<=f;xgsf?UPF z-q8(}THQ`JmcduOa{#Nz+r=zU$7e+gP*@y&5ujQ-5xZ-~59yQM?*tkoeA&S#QQ3QN za}MouYXzV7iBQcip4?|2Ne@t&Iyy=9Kmczz#5+$-5f;eRTI^JtphrA%_9@7J;Lc`dZ@7na zdK|4uENf=kI?)JTkufK|(f&f1MR&32AB8ZL##wZ75tPwk7Huek=`&)A)M{)ZCwXtf(AnNLwC{G7UtG%IQcM=Iv2KPpL8H5 zd`=*9K^UHxmISd(A|{F~xgmfKsEYw&RQ6-W8AUoFT6IWcAS@UX-`jSxCi>&_x$k-2 z_c`x*&gnTZr8_aD8@UCN5saXxhP)inkYg}F4u1eqc%EONm!U!3Cro71m{onz_`8|T zlyh(89u2Nm9zakxEU2U!4!X9R3u0EqAX%BkNr_ydfkE=9X3s{j{KNQU$}Gw_2`Gku zY{pE5F zH6kjzY)Ke3Ct)H5(`J5qT>^{Msr5^;@@C2vA{mwVA|;+Bt>mo5ju!83G4XXR4)CbE zTkZygif+Lo$$vrxC___1v6_;xB z)GNPUE3`_40V8+^v>%5xD z!G}ULMR2wXgIV?i{H94ZY(w4Gg4JE!U8oeXiB(ER2kYD9?+W@``r5m@f-Kn9y*cz< zIhg6VEp*ZaMKoax&2vCi;}M3^5+NlS(x>O7qfE^6_=9b%tGkc2_HOof5WJLVH&&Eo zR9u{^NU+c$2fhFid+1XKFg9uzO)<=NW@LXgmmRZ*{&Ilpi2+&6(yR&gv=V$TQ$gz{ ZKT*Qzprf@#d%DvO;!e-xRKh!1e*@*o+KvDK diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm index 98dabfb1bbd67a4ab372327b6b328f9d46d2355a..735533a89742f7416fa67be5b74b862d3e84dfb7 100644 GIT binary patch delta 1806 zcmZ`(Yitx%6u#%qE}eF|?a<(+u&+DY(r)Wo9tns|Bprycl`Xs5LLnl?S}Sxd3uRG* z;nCD$02LdrWY$Q`f?y;Ovtfc%in8*CNLURaRf&}N$ZC94LQRACIJ2{@HPIh;zB#Y& zoO{lh8N6W`ykSZH46>DqVo`x)0~?41P$2R@;agbBzoF-#S$|i!l24C2^y`xrTJ}D<>C0?fiq8!o#^{c@3k0s=#%%!GD zL=_`m2YSjOo^Gfzvi#m4gMqe1)IdHtV22R*1w4kbA)pBMTMpU7ihZ=7dPM_M)Jx^C z-W|LR_FM|o4hdetux140-n*oQ|64B z;#M<0VfBI>R3@`x^*oI*q9zqH_B{0xBQ{Mj@?f)P%6}R3Yt7$LaoDZq$w7HBzu5Be z|CjgyEaoeg2WVW;4=!(l@-e=Qpk#|25)@3Rnq=xrWd*A{awFxT*_aiSFnq zp|FJ4JasbP%(wtHafsH_VK?vUXyLDS7M29Po{)_&kDAF|Fl;0Ik2L|B$$C&Zz@t~3 zeB+ul9nESKiMiE&h^SaaZcuIt#SRGHivLB0kppWH26Ms@GN8v^7QGkH{Lwv-FAK1{FUkbF5 z@ZAUQL*?ZIy@fR4(w81ih!Ehv9ouUk&9+yWmg}>+-;c8o^Fsqug%&xWUl`~VjEH+r z%!jf&PGkIXqj}WP>0_drbY&M~kDJF+%Q4ZfsZB-^(UU%aMy{P=DDN`I51BCVWKRcSO=gN7&J>>JQ8l75s^}Xz`#rF9jP>f3v z28`e?7!Qj)OS%qJ*eYzHb+k?n;5^^14l9;ihrCv^R)JYIGi$EaB~o#=J?f8sUHJZn z{m4}~TfR(;ZD_51wxhF_sHYuLX{d;hYC_0N#Jdpp;j!T%_?1be1hq9Nj9K5ocbc`{ za!6uqW2`p1Hi}H$PVKEqm`#&T?JGY_rD>;jvl42W?l_U7m=Na#jw9n7371q<-x^!Z zqH8y>_O7Q}JMpLEl1kH552V|z?ePI)d)!iK9rF7ocwZX#PPw&f zKJahNxTQSf*0FW%1pg|g(7wKvsG~Wdv%L*3;lV4R+vBZ9bGCb=(seQ+l}INe+7a9F z2zZE^KZ#_t-b?R-knE>}Pq8^RbenULudVtVl1f(NhW)k-R%>gfGd H@J8O>IXA_+ delta 1810 zcmZ`(e{54#6u#%amcH$++hdtcx32B&+piAG6b*z-LwKM`H>&G4WK%?)bF$5`F*-yI zLo&fk5NNz=Yl5aML?uC8cp(fKFh>wVVytn-CWpz7cixR%F~qJIhJOIr3}!G=F*jQhvqcfI`JeDLtm9Yd1!&NY3KLm0?$9O|tTt-r z^EC^dE#psB?m~EB(SCet!9|r+$5WnuTS45Rin4>*-IOTBI*4+O=JRd@`#&DPLYZBS zl1^3ZRBRY2*YIdfrJm*Y8X0snuc12fg+2?^aJSE?Z`Sx+f+g&foh;8yN2ns|I7SsJ z*J?ZKu7f3=0(awrBIw?PfZB(eN;Iv0Inbbkf8Vgd5_6;^28~z<1_g~uuI%LxH5M$L zbA^p5e#EGN>~$?kM<81v5jVN0F{Yy-_vt=rg&1zz?nlQ<0czvr2n;U3d0X5pO)@y?P5sz%_1!&Z4 z9r+X*dDUa%S*eVxU^|CyFAXZZw__cDr7I`jt2q5;!kp@0@__Yb!vEOhql3u^D%bH1 zo2F?vX}KikP)DFs4SUq|M{?jN1f_@}jsecdc=ylLmTW)nwBv_ysEO2sfIcB!?Ze*d zfQ4QPlx89PxcwR33hY=-5l-w38^F)~yDRLoWiBEyk-;)*Kp@K~VWJv?PA1B0wHJ4n z1KgvXdiEs>K3@Oaq%#$7(BpHML5~-iL6tl4A$H1ZdEK4>63*>;gu-3iz3<(00wI+^ zNF@-|Sxg{c_+R@5;BIYTza6XNkpqXZxI2T)1Z()Cp;9#Vh8_T@)4mH|Gvdz`f9*5D z;3v{??wa&!cU(R|`I({R=>K(SR}LLxTK_u{5$d>O2|A!JvaijJCs7d z*+f?|D=X?}g#)WdgPF)HCAmqi(|#K15_FXZM^`|}L8ecJjM?<1&X&!YYBcFlM_qjE zbTcL|JhNS|@#V8_z^0xZV`#+39>+c2G=9jEE+p&Uh49>Sh0vtA&;6ov?dNZToXj-Z z(8NMvL28!x$xlyXE4IaU8MKclJpi@GuAI=-H*6}_CcZohIEZ}Us@|?QuD+eTTbjOo z3v1Du-}mKezfE1XaMP3>31w5SFRpbN(!EfOeluVz1ZL=G#&jzhrM%REr#*P!h7LyREjvIDz&SN^=)bC4z#rPb@X%xSfIUUYbd)MY&7Z&ec^#Z zI^ztjDu=3ugAAo*LW(n_kIzewF)7#E5@=`LJ$ Date: Thu, 8 Feb 2018 22:36:24 +0100 Subject: [PATCH 2/6] fix runtime_test --- .../release/polkadot_runtime.compact.wasm | Bin 77991 -> 77991 bytes .../release/polkadot_runtime.wasm | Bin 78040 -> 78040 bytes substrate/executor/src/wasm_executor.rs | 11 +++ substrate/executor/wasm/src/lib.rs | 91 ++++++++---------- .../release/runtime_test.compact.wasm | Bin 13991 -> 14152 bytes .../release/runtime_test.wasm | Bin 14116 -> 14248 bytes substrate/runtime-io/with_std.rs | 29 +++--- substrate/runtime-io/without_std.rs | 89 +++++++++++------ 8 files changed, 124 insertions(+), 96 deletions(-) diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm index 4f3bdfc57d502916d6b2c4bf1dfeac3f3fae2273..928c72939d1c2d74c34cb180a24421358565776a 100644 GIT binary patch delta 555 zcmZ4fkY)KpmJQDs#aWp+cp-p;kBgg^k(ZH!i-VDC@?S>3dS~I(iqz!NlGON;qQt!7 z#N?99{5%F1zO>A|#GK6H)cB;F{N!u~SN<{}HzlzozbHOAzcjCe!Ho+pQq17aomg6u zkzbTql9^h};K7|zT2dKblwVwuTEyVV$ z&8L{^9T7Pen^9vfptCLP+$S+`ojsNfx4c6_#j;kTtEg;mq<5A*Jg|EeTiz=agLHoY2>^9V_JeiX_6G=W);zXWY4eGfcf}@O zd+}-OQpWe1vJw-77#J)W7#J=9X)z$Z0*Kjwn89&^>U13~Mmt8;>F?DUrDR{Ia&sgI z!z4cdc@99HG+616>Fcx@H8tj_aSIp#1-XENK#GA8EV)6Ao2$4eSwFELQ?IC)!SR6F b^#59n@>~zpxY<+`@)C1Xw=dLYWMc&Y+P$I{ delta 522 zcmZ4fkY)KpmJQDs#d#rsm5GCckBgg^k(ZH!i;;_C@?S>3dI#auiqz!NlGON;qQt!7 z#N?99{5%FnzO>A|#GK6H)cB;F{N!u~C;l=ZHzlzozbHOAzcjCe!I=v#Qq17Oomg6u zkzbTql9^h};L4p+T2dKblwVwuTEyVS$ z&8L{^9T;0SdpX~7+QnUHWx_yj{9-Aj`h-75+ocwm< z5|uA1W=tQL6qp?u&6wUW18H_MrY|5q$c7If0if=!o4~qnZVC|ItkP;A#u&OeboO2r zrXQ-CMHW=D0=a!lHJCwM#baBQCU5@#Y4f!gcg40YWqhxx#PLChfq{(y2!KX$b6f!O zq`|xvRc;kV5NrBJNk&DD6{_3<2Y`}XKoMae21_{}Q03+-E=txA|#GK6H)cB;F{N!u~H~umpHzlzozbHOAzcjCe!JP{(Qq17Nomg6u zkzbTql9^h};K`j*T2dKblwVwuTEyVR$H!qGk|g%5`fci`Q8uCXRZ> z%^#S$92kFWu6DlVxOv|q12M+%&F^>YWnucFvU%O!N>(6O5Pn_n|HTOWny%k9N3wt@

&X#%SPha;mI(;7A)&2Gjt1;qaWl-K|g_@FxZTBj1z z9JR^6I!`c$PCncf2iEm~LxBaP>klW82I_hO;)8TGZ~+-WU9R0AU7Itz_c1a$ZPw_G zWMp)n+|;)Otos9#0y9YW8)hI4)cpm-2kHI*5&-J<>Idu2>kkm#9Cd81(&nEp?}|-k zfB9+aHOBXvvJw-77#J)W7#J=9X)z$Z0*Kjwn89&^>hxGGMmt8;=?WT*QnD{pxj7Pq zVUiz!JO?088m#ok^!r+jni_M|xCIP=f?PmBAjQB4mfWDm%~f2Kte;qrsaI6Y;CMi7 ax`8&MJl6v?ZZ;K#yu{qp?U%F}*;oOPv!e6> delta 519 zcmccdkmbfhmJQDt#d#rsm5GCckBgg^k(ZH!i;;_C@;}DndPm{Ziqz!NlGON;qQt!7 z#N?99{5%FHzO>A|#GK6H)cB;F{N!u~XZ|uEHzlzozbHOAzcjCe!G#MhQq17Womg6u zkzbTql9^h};KrR&T2dKblwVwuTEyVa$H!qGk|k%5`fci`Q8uCXRZ> z%^#S$92i?RS3BQw-28DxDkEd~=I~WhnHW7Lzg?5a^hITIz*=$c7F9E*4QvV=j(=1p z7p+xdTA@05+S(J0;gjRn#evl9Uk6dsz@@+fQuA;fNX=%}_4^nZJvSfO5Xs2sHCb-c z5|uA1W=tQL6qp?u&6wUW18H_MrY|5q$c7If0if<@o4~rcHU|iA4sA6MV+`BeHhV7% z(+}0nt_vzzf!zH|HJCx%pkrH=CO`TAX*2uFyJB0fF}~N7<@g}Pz`(`;1VE#>IW7Qs z(qLYTD!0n?T4_cVEe6LGs@wtxfHGV_8DSu11gkip%FR_=l&qgvkf~Qx%;0!Ib^1ze zMtPkNs@!ZU3VDgSsSJ)kRJkPtfLbhpIs$;S7?558#1I=Ns7;U6Vzgsao35zMD7F2H IHX{ow0Ik!WOaK4? diff --git a/substrate/executor/src/wasm_executor.rs b/substrate/executor/src/wasm_executor.rs index 60f437081a818..85c1e0e61bdb6 100644 --- a/substrate/executor/src/wasm_executor.rs +++ b/substrate/executor/src/wasm_executor.rs @@ -423,6 +423,17 @@ mod tests { let mut calldata = vec![]; calldata.extend_from_slice(key.public().as_ref()); calldata.extend_from_slice(sig.as_ref()); + + assert_eq!( + WasmExecutor.call(&mut ext, &test_code[..], "test_ed25519_verify", &calldata).unwrap(), + vec![1] + ); + + let other_sig = key.sign(b"all is not ok!"); + let mut calldata = vec![]; + calldata.extend_from_slice(key.public().as_ref()); + calldata.extend_from_slice(other_sig.as_ref()); + assert_eq!( WasmExecutor.call(&mut ext, &test_code[..], "test_ed25519_verify", &calldata).unwrap(), vec![0] diff --git a/substrate/executor/wasm/src/lib.rs b/substrate/executor/wasm/src/lib.rs index 2002d3cefc94d..11401a39d7b45 100644 --- a/substrate/executor/wasm/src/lib.rs +++ b/substrate/executor/wasm/src/lib.rs @@ -13,57 +13,42 @@ use runtime_io::{ twox_128, twox_256, ed25519_verify, enumerated_trie_root }; -fn test_blake2_256(input: &[u8]) -> Vec { - blake2_256(&input).to_vec() -} - -fn test_twox_256(input: &[u8]) -> Vec { - twox_256(&input).to_vec() -} - -fn test_twox_128(input: &[u8]) -> Vec { - twox_128(&input).to_vec() -} - -fn test_ed25519_verify(input: &[u8]) -> Vec { - let sig = &input[0..64]; - let pubkey = &input[64..96]; - let msg = b"all ok!"; - [ed25519_verify(sig, &msg[..], pubkey) as u8].to_vec() -} - -fn test_enumerated_trie_root(_input: &[u8]) -> Vec { - enumerated_trie_root(&[&b"zero"[..], &b"one"[..], &b"two"[..]]).to_vec() -} - -fn test_data_in(input: &[u8]) -> Vec { - print("set_storage"); - set_storage(b"input", &input); - - print("storage"); - let foo = storage(b"foo"); - - print("set_storage"); - set_storage(b"baz", &foo); - - print("finished!"); - b"all ok!".to_vec() -} - -fn test_empty_return(_input: &[u8]) -> Vec { - Vec::new() -} - -fn test_panic(_input: &[u8]) -> Vec { - panic!("test panic"); -} - -fn test_conditional_panic(input: &[u8]) -> Vec { - if input.len() > 0 { - panic!("test panic"); +impl_stubs!( + test_data_in NO_DECODE => |input| { + print("set_storage"); + set_storage(b"input", input); + + print("storage"); + let foo = storage(b"foo"); + + print("set_storage"); + set_storage(b"baz", &foo); + + print("finished!"); + b"all ok!".to_vec() + }, + test_empty_return NO_DECODE => |_| Vec::new(), + test_panic NO_DECODE => |_| panic!("test panic"), + test_conditional_panic NO_DECODE => |input: &[u8]| { + if input.len() > 0 { + panic!("test panic") + } + input.to_vec() + }, + test_blake2_256 NO_DECODE => |input| blake2_256(input).to_vec(), + test_twox_256 NO_DECODE => |input| twox_256(input).to_vec(), + test_twox_128 NO_DECODE => |input| twox_128(input).to_vec(), + test_ed25519_verify NO_DECODE => |input: &[u8]| { + let mut pubkey = [0; 32]; + let mut sig = [0; 64]; + + pubkey.copy_from_slice(&input[0..32]); + sig.copy_from_slice(&input[32..96]); + + let msg = b"all ok!"; + [ed25519_verify(&sig, &msg[..], &pubkey) as u8].to_vec() + }, + test_enumerated_trie_root NO_DECODE => |_| { + enumerated_trie_root(&[&b"zero"[..], &b"one"[..], &b"two"[..]]).to_vec() } - input.to_vec() -} - -impl_stubs!(test_data_in, test_empty_return, test_panic, test_conditional_panic, - test_blake2_256, test_twox_256, test_twox_128, test_ed25519_verify, test_enumerated_trie_root); +); diff --git a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index 2b8e909b3e4b2e6608e409e5a5b1cf6d86e1fa33..6296f219c64cbef48b5a3a7428b3847c0eccfa23 100644 GIT binary patch delta 2749 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 V20wZ*%fN>RvzF4GR(~Iv{2!QdG`9c% diff --git a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm index b3e3b8389158fdd46669b05e916da8b65b536052..0f00a9675481128e88540e2386816fa406722f2b 100644 GIT binary patch delta 2709 zcmZuyU2I%O6`q;BcfGr_n~d#^y}Ndj@y4;&ak6&Y*h$-zdXgrJ1ff+cQK3?twSArJ z+WW)qHTeN`{a_&;Q0sO=B_I#34r6eQbY|%r~)G_kw;V(;fFj?3*{jQA@R+% z*NJGaeeXBtJ9EyQIp@smO5t{K>8xPYDt+ZrOLhC9)jKbIfyz+xu?QZ&O=-Xi1Z)=I z6pzjH9h#_yU8mwsOlRE8M7BWowtAwIFS*wz%8olM(^>1-{}Bfv@La<(urU$~krOp};D@8qXS*Gb$P?aycC=898fzco{K9C9ESp+phhGBhZU96dM?dgo%#Zz*F{Ht~vrBE>8vW|O`# zX0dTeBSeWF&^?qZp}63xTiKFGD#B`5wFoYKii|O$PAQ-C39E-lUy5P+&g|2mw`Z^E zS7pk-PGFSQAIj6#VZy(v|04%&p$Mp>J$;6HQ-7M=Pleud=%>0rxlGeK)7wXP*!rGB z&(j_16aC%ZZcO}f?=3KA4G(|q@f(LvqnUBf{mL$N!7uN5h9r+a5g~5$ts*-vr2dp1Pel-DIjTP5`0nh zH*zsTJ)f8%bH;5v0of#Hn>H~DdhQ8QR8-hWaxTK4pkvIHa5TnBkO0>JTO^0?rzCe8 zQ`6EOW!HNA21-3G%4~0e=8y&1BK>FNcNX_@B~iUYgsX-r3-}4OcPv3b1W7fY=!z1=0zBT(*D(d6@0R~|<@QwO4 z@f5Q+e5&Eozij(&^Z}aklnlaK3Ol+0gyN6wr>sp&^y`-BORe`U6L?SoP5^G&x)M!W zD}K>me>=KP53KvQ^=J#DzYh@()o{+Vgsm5%o%^67+tlrV=*J#c{o=6xp!+-rgu)&IQz>-50KohF?!EJLCf7?PGLPk=~MD5*CCKWJNur~$PVQ8lKPh59`c zDg9cot8J@I^{BOW^(Iw~sJaKb{;S}NjP~egc#!tg$HSu*P3jLjej+vz(U)XM-34Ay zn{j=;^WQX~E3wD%eJ}Pse4mJ$u^S)7_nr9f4zI`1=0VYCvJo>Os+Ab(z&xfo)Ndr7 zK9Lw>F-g(l0cCrz>NNLF zW^S0%%Y!r7Lbh_nnZ}*Aj!O_%qb$xsXb>K9^|uCw?1O}m1N!}e_{&L*EWAX$OSyH! zDZ^Kda$m84C08-Poer;*w@zhBnW?OMUE=C3&&(CC5*!U4TZ3&Y-YvZCc>ll%2?B}Q zqI&PieHJkXB6;Lb$2NT2ekq+!zl=zHJa!4o;!Kg}Y(hGKYmljD_`t{Kbm7?C8KO2V zF2rX$WvWdEIp+e(9WR5-AI4Cw=75a*zjP%4jMeYeDWGki{8! z355u93fKth7Y2teE`)e%({Hh4exp6N%OSqU`w^9=pOQ{tTBhJ6#4RJjMTm<5dG(4@ zkd?XYRJL&0INk{9^iZOD56T)+VG6PVi~xyx0Covd6hbFj6+^H~oJX6h8&A&ezG|Fz zc+AemDsHCiR%FJ-@*A8-NF82Qvw)63{dY77FWs4D}|q!o1B}&%M&jbJk>aDWab_{uQSQ! delta 2589 zcmZ`*TWDOz8J?Lvd!2K3XLVh#h;zP~@Bin&GppDk%*1Zl9QikS>)w96S7noO6|quCtkjJn&*T%o)$TFjK^i#f7C# zXx6`N{mIB?M0Kfkp;nn%tXF?zqTOM(#nnTS@Y-I^j!CK(7Xzmq98v3yDxp@I)Q_pE zHmiR?dF|c3-)6K$|8rjtZCPuSgBERFOVy1q@1~^|y}H=&MZ^2vA$CLt5pr^7h@AvN z@V&+()+L{i`gY^l=(2B!^@F#D*kQmepYCZ&S$F(GuD#ZDk48W9Z^>cE$d?0pIF{mf zgF+In?)ybTztH{*an&ATFUpWw2A)(Kjt+MGhlaJM^C^6fc3#H!6L)RxAH;fi|L;3C zJd(+v*atKBJR$-3*n>!!%j_(5TXN(uY{n!-4Fbp^30wsuT*hQ2!L-jPI>bz!#Eg1i zBeyU1JVza^;>~Qy(XYgNsnkD+|C&bh5BI!8@9V$rX$SM)*okJx*kXzeF&hB^BzE^5 zy&mhfZiHd!|0*p$Kr|+~gr`84^zbL(&p$`bzQxD)d0tKt;qOT&=W- zuOZh0P{s+ofg}tpXfJtU4alXwn#4OW$hp1Xh0(^pUB^4K3^(wDBKenn8Rxo5mtgoPmqHNG_Iqs{>(JAlXQ0bp(bqgZzFLbS;Qr$2 zG~9cdT6@jd?z3K|v_psdopguO`>bE-tZ!wT{!}0Ix0=a*$^QYUfB8EqHz=dKvXST8 zP*7yE^(X0Zca}#^Ii{VTl2Z;Ut`HM~B*Jl7E3^LkcmXUr3fSvQ(;L|GftJLk>9lG5)ocG}6*IG{#WpS(K2tt(2 z{kZgG{yaL@z^#j!VxFiN_vCXKqFT8JHxyBlb6k+4rEw5C_VL}MQOVl#uu`w({cnjM&0z{CIu2LSI zNEgx*+46$KHC>#V&0iqu4i2qC9>rV3TaWh>*b4$NfBJHF%v@|Ab^mGdV-FX`RUITF z*47b(=HciFAw6Kv0F9y3l#oUsQ5(C?9KxBT%Pv~HZZz>Yw!#)FmGm zHTX2~{yeag(z1`sDpbQ@*MU$VH6VJo%fu}oU!r=YXI3vAu=MTTw&^?m$JTDb8jir# zeLs&Cur%4P0Kc65XMUbEiY80}>;xVI;y5`2^a00!TVXE;_^sVOrR)2_fi`tF_}KUF z9{H{XA6KzdEpvXhdT3?Bx)(7M^fESR6{%lmGLxH>Nf_bWGFzD7Ty)6`=Q252n$1pRbJND~Cg)8u zTax+tvT-$@pU+KV=Q>@oIZLH5wl)|2rV@ArFoq!_m{*$zmbPi4eq-}?w4?obg4>;o z0tBYiS1{YCAJjMPuMB$0;bH~K5;|3&nFY+5qa*$8167CD$#H~MKDSdW#EPck(3pR# zJq2K!duYSqClSKQI8iskTpWX-0fOkG5UOE)rY{z*g}HC1@|$7(=f2L=a)gU2^v#&o zfR1bMD%c$>&5x}_^h{s8u@>Qu8yhNJlIb$S+KlK^{oi8iV(r8JLCO~E*B%^vfwJ{R s-F4^$TWQj79QrA%Hm`*b&rx|j&SS^m#|&lx_~pT@#!aX7@h2z#2Wl)b7XSbN diff --git a/substrate/runtime-io/with_std.rs b/substrate/runtime-io/with_std.rs index bcedb481162b5..cb01133a6c112 100644 --- a/substrate/runtime-io/with_std.rs +++ b/substrate/runtime-io/with_std.rs @@ -126,25 +126,30 @@ pub fn print(value: T) { #[macro_export] macro_rules! impl_stubs { - ( $( $name:ident => $invoke:expr ),* ) => { + ( $( $new_name:ident $($nodecode:ident)* => $invoke: expr ),*) => { /// Dispatch logic for the native runtime. - pub fn dispatch(method: &str, mut data: &[u8]) -> Option> { + pub fn dispatch(method: &str, data: &[u8]) -> Option> { match method { $( - stringify!($name) => { - let input = match $crate::codec::Slicable::decode(&mut data) { - Some(input) => input, - None => panic!("Bad input data provided to {}", stringify!($name)), - }; - - let output = $invoke(input); - Some($crate::codec::Slicable::to_vec(&output)) - } + stringify!($new_name) => { impl_stubs!(@METHOD data $new_name $($nodecode)* => $invoke) } )* _ => None, } } - } + }; + (@METHOD $data: ident $new_name: ident NO_DECODE => $invoke:expr) => { + Some($invoke($data)) + }; + (@METHOD $data: ident $new_name: ident => $invoke:expr) => {{ + let mut data = $data; + let input = match $crate::codec::Slicable::decode(&mut data) { + Some(input) => input, + None => panic!("Bad input data provided to {}", stringify!($new_name)), + }; + + let output = $invoke(input); + Some($crate::codec::Slicable::to_vec(&output)) + }} } #[cfg(test)] diff --git a/substrate/runtime-io/without_std.rs b/substrate/runtime-io/without_std.rs index a4d8e4076d5ee..ecadddeeabdad 100644 --- a/substrate/runtime-io/without_std.rs +++ b/substrate/runtime-io/without_std.rs @@ -14,9 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -extern crate substrate_runtime_std as rstd; + extern crate substrate_primitives as primitives; +#[doc(hidden)] +pub extern crate substrate_runtime_std as rstd; + #[doc(hidden)] pub extern crate substrate_codec as codec; @@ -141,10 +144,10 @@ pub fn twox_128(data: &[u8]) -> [u8; 16] { } /// Verify a ed25519 signature. -pub fn ed25519_verify(sig: &[u8], msg: &[u8], pubkey: &[u8]) -> bool { - sig.len() == 64 && pubkey.len() == 32 && unsafe { - ext_ed25519_verify(msg.as_ptr(), msg.len() as u32, sig.as_ptr(), pubkey.as_ptr()) - } == 0 +pub fn ed25519_verify(sig: &[u8; 64], msg: &[u8], pubkey: &[u8; 32]) -> bool { + unsafe { + ext_ed25519_verify(msg.as_ptr(), msg.len() as u32, sig.as_ptr(), pubkey.as_ptr()) == 0 + } } /// Trait for things which can be printed. @@ -181,33 +184,57 @@ pub fn print(value: T) { #[macro_export] macro_rules! impl_stubs { - ( $( $new_name:ident => $invoke:expr ),* ) => { + ( $( $new_name:ident $($nodecode:ident)* => $invoke:expr ),* ) => { $( - #[no_mangle] - pub fn $new_name(input_data: *mut u8, input_len: usize) -> u64 { - let mut input = if input_len == 0 { - &[0u8; 0] - } else { - unsafe { - $crate::slice::from_raw_parts(input_data, input_len) - } - }; - - let input = match $crate::codec::Slicable::decode(&mut input) { - Some(input) => input, - None => panic!("Bad input data provided to {}", stringify!($name)), - }; - - let output = ($invoke)(input); - let output = $crate::codec::Slicable::to_vec(&output); - let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); - - // Leak the output vector to avoid it being freed. - // This is fine in a WASM context since the heap - // will be discarded after the call. - ::core::mem::forget(output); - res - } + impl_stubs!(@METHOD $new_name $($nodecode)* => $invoke); )* + }; + ( @METHOD $new_name:ident NO_DECODE => $invoke:expr ) => { + #[no_mangle] + pub fn $new_name(input_data: *mut u8, input_len: usize) -> u64 { + let input: &[u8] = if input_len == 0 { + &[0u8; 0] + } else { + unsafe { + $crate::slice::from_raw_parts(input_data, input_len) + } + }; + + let output: $crate::rstd::vec::Vec = $invoke(input); + let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); + + // Leak the output vector to avoid it being freed. + // This is fine in a WASM context since the heap + // will be discarded after the call. + ::core::mem::forget(output); + res + } + }; + ( @METHOD $new_name:ident => $invoke:expr ) => { + #[no_mangle] + pub fn $new_name(input_data: *mut u8, input_len: usize) -> u64 { + let mut input = if input_len == 0 { + &[0u8; 0] + } else { + unsafe { + $crate::slice::from_raw_parts(input_data, input_len) + } + }; + + let input = match $crate::codec::Slicable::decode(&mut input) { + Some(input) => input, + None => panic!("Bad input data provided to {}", stringify!($name)), + }; + + let output = ($invoke)(input); + let output = $crate::codec::Slicable::to_vec(&output); + let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); + + // Leak the output vector to avoid it being freed. + // This is fine in a WASM context since the heap + // will be discarded after the call. + ::core::mem::forget(output); + res + } } } From 74a897df2c527d401d09db466a400de5f836c407 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 9 Feb 2018 13:24:30 +0100 Subject: [PATCH 3/6] Introduce toy runtime for testing inside substrate. (#66) * Introduce simple blockchain runtime for substrate tests. * Remove bad files. * Add needed wasm binaries. * Refactoring. - Repot files in test-runtime. - Rename troublesome `Joiner::join` to `Joiner::and`. - Rework `Slicable` to dedup code. * More fixes and refactoring * Rebuild substrate test wasm. * Fix merge errors. * Rename the disasterously named `to_vec` to `encode`. Also rename `as_slice_then` to `with_encoded`. * Tests for toy runtime. * Fix doc nit --- .gitignore | 1 + Cargo.lock | 30 + Cargo.toml | 5 +- build.sh | 5 + polkadot/cli/src/lib.rs | 4 +- polkadot/executor/Cargo.toml | 1 + polkadot/executor/src/lib.rs | 44 +- polkadot/primitives/src/block.rs | 36 +- polkadot/primitives/src/parachain.rs | 30 +- polkadot/primitives/src/transaction.rs | 96 +- polkadot/runtime/Cargo.toml | 2 + .../runtime/src/{support => }/environment.rs | 0 polkadot/runtime/src/genesismap.rs | 31 +- polkadot/runtime/src/lib.rs | 22 +- polkadot/runtime/src/runtime/consensus.rs | 2 +- polkadot/runtime/src/runtime/governance.rs | 19 +- polkadot/runtime/src/runtime/parachains.rs | 11 +- polkadot/runtime/src/runtime/session.rs | 11 +- polkadot/runtime/src/runtime/staking.rs | 33 +- polkadot/runtime/src/runtime/system.rs | 29 +- polkadot/runtime/src/runtime/timestamp.rs | 4 +- polkadot/runtime/src/support/statichex.rs | 61 -- polkadot/runtime/src/support/testing.rs | 83 -- polkadot/runtime/wasm/Cargo.lock | 14 + polkadot/runtime/wasm/Cargo.toml | 4 +- .../release/polkadot_runtime.compact.wasm | Bin 77991 -> 75751 bytes .../release/polkadot_runtime.wasm | Bin 78040 -> 75800 bytes substrate/client/Cargo.toml | 14 +- .../cli => substrate/client}/src/genesis.rs | 102 +- substrate/client/src/in_mem.rs | 2 +- substrate/client/src/lib.rs | 6 +- substrate/codec/src/joiner.rs | 6 +- substrate/codec/src/keyedvec.rs | 2 +- substrate/codec/src/slicable.rs | 55 +- substrate/executor/src/wasm_executor.rs | 8 +- substrate/executor/wasm/src/lib.rs | 12 +- .../release/runtime_test.compact.wasm | Bin 13991 -> 13991 bytes .../release/runtime_test.wasm | Bin 14116 -> 14116 bytes substrate/network/src/lib.rs | 2 +- substrate/primitives/src/block.rs | 40 +- substrate/primitives/src/hash.rs | 4 +- substrate/primitives/src/lib.rs | 9 + substrate/runtime-io/with_std.rs | 2 +- substrate/runtime-io/without_std.rs | 2 +- substrate/runtime-support/Cargo.toml | 26 + .../runtime-support/src}/hashable.rs | 6 +- .../runtime-support/src/lib.rs | 19 +- .../runtime-support/src}/storage.rs | 57 +- substrate/runtime-support/src/testing.rs | 28 + substrate/serializer/src/lib.rs | 2 +- substrate/test-runtime/Cargo.toml | 24 + substrate/test-runtime/src/block.rs | 48 + substrate/test-runtime/src/genesismap.rs | 68 ++ substrate/test-runtime/src/lib.rs | 74 ++ substrate/test-runtime/src/system.rs | 178 ++++ substrate/test-runtime/src/transaction.rs | 56 ++ .../test-runtime/src/unchecked_transaction.rs | 63 ++ substrate/test-runtime/wasm/Cargo.lock | 881 ++++++++++++++++++ substrate/test-runtime/wasm/Cargo.toml | 30 + substrate/test-runtime/wasm/build.sh | 8 + substrate/test-runtime/wasm/genesis.wasm | Bin 0 -> 31744 bytes substrate/test-runtime/wasm/init.sh | 6 + substrate/test-runtime/wasm/src | 1 + .../substrate_test_runtime.compact.wasm | Bin 0 -> 31904 bytes .../release/substrate_test_runtime.wasm | Bin 0 -> 31984 bytes 65 files changed, 1923 insertions(+), 496 deletions(-) create mode 100755 build.sh rename polkadot/runtime/src/{support => }/environment.rs (100%) delete mode 100644 polkadot/runtime/src/support/statichex.rs delete mode 100644 polkadot/runtime/src/support/testing.rs rename {polkadot/cli => substrate/client}/src/genesis.rs (53%) create mode 100644 substrate/runtime-support/Cargo.toml rename {polkadot/runtime/src/support => substrate/runtime-support/src}/hashable.rs (92%) rename polkadot/runtime/src/support/mod.rs => substrate/runtime-support/src/lib.rs (73%) rename {polkadot/runtime/src/support => substrate/runtime-support/src}/storage.rs (89%) create mode 100644 substrate/runtime-support/src/testing.rs create mode 100644 substrate/test-runtime/Cargo.toml create mode 100644 substrate/test-runtime/src/block.rs create mode 100644 substrate/test-runtime/src/genesismap.rs create mode 100644 substrate/test-runtime/src/lib.rs create mode 100644 substrate/test-runtime/src/system.rs create mode 100644 substrate/test-runtime/src/transaction.rs create mode 100644 substrate/test-runtime/src/unchecked_transaction.rs create mode 100644 substrate/test-runtime/wasm/Cargo.lock create mode 100644 substrate/test-runtime/wasm/Cargo.toml create mode 100755 substrate/test-runtime/wasm/build.sh create mode 100644 substrate/test-runtime/wasm/genesis.wasm create mode 100755 substrate/test-runtime/wasm/init.sh create mode 120000 substrate/test-runtime/wasm/src create mode 100644 substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm create mode 100644 substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm diff --git a/.gitignore b/.gitignore index 9155c1d6e1293..44aa658e9208f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ *.swp polkadot/runtime/wasm/target/ substrate/executor/wasm/target/ +substrate/test-runtime/wasm/target/ **/._* diff --git a/Cargo.lock b/Cargo.lock index 4920d3e6677da..aae23858ada1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1023,6 +1023,7 @@ dependencies = [ "substrate-executor 0.1.0", "substrate-primitives 0.1.0", "substrate-runtime-io 0.1.0", + "substrate-runtime-support 0.1.0", "substrate-state-machine 0.1.0", "triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1052,6 +1053,7 @@ dependencies = [ "substrate-primitives 0.1.0", "substrate-runtime-io 0.1.0", "substrate-runtime-std 0.1.0", + "substrate-runtime-support 0.1.0", ] [[package]] @@ -1386,8 +1388,10 @@ dependencies = [ "substrate-codec 0.1.0", "substrate-executor 0.1.0", "substrate-primitives 0.1.0", + "substrate-runtime-support 0.1.0", "substrate-serializer 0.1.0", "substrate-state-machine 0.1.0", + "substrate-test-runtime 0.1.0", "triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1507,6 +1511,19 @@ dependencies = [ "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "substrate-runtime-support" +version = "0.1.0" +dependencies = [ + "environmental 0.1.0", + "hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-codec 0.1.0", + "substrate-primitives 0.1.0", + "substrate-runtime-io 0.1.0", + "substrate-runtime-std 0.1.0", + "substrate-state-machine 0.1.0", +] + [[package]] name = "substrate-serializer" version = "0.1.0" @@ -1528,6 +1545,19 @@ dependencies = [ "triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "substrate-test-runtime" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-codec 0.1.0", + "substrate-primitives 0.1.0", + "substrate-runtime-io 0.1.0", + "substrate-runtime-std 0.1.0", + "substrate-runtime-support 0.1.0", +] + [[package]] name = "subtle" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index a0db795c2e911..e46ed6d72525a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,12 +31,15 @@ members = [ "substrate/rpc", "substrate/runtime-io", "substrate/runtime-std", + "substrate/runtime-support", "substrate/serializer", "substrate/state-machine", + "substrate/test-runtime", ] exclude = [ - "substrate/executor/wasm", "polkadot/runtime/wasm", + "substrate/executor/wasm", "substrate/pwasm-alloc", "substrate/pwasm-libc", + "substrate/test-runtime/wasm", ] diff --git a/build.sh b/build.sh new file mode 100755 index 0000000000000..4e5e035dc468f --- /dev/null +++ b/build.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +cd substrate/executor/wasm && ./build.sh && cd ../../.. +cd substrate/test-runtime/wasm && ./build.sh && cd ../../.. +cd polkadot/runtime/wasm && ./build.sh && cd ../../.. diff --git a/polkadot/cli/src/lib.rs b/polkadot/cli/src/lib.rs index ac452bfef38a0..59e6ef270e1aa 100644 --- a/polkadot/cli/src/lib.rs +++ b/polkadot/cli/src/lib.rs @@ -39,11 +39,11 @@ extern crate error_chain; #[macro_use] extern crate log; -mod genesis; pub mod error; use codec::Slicable; use polkadot_runtime::genesismap::{additional_storage_with_genesis, GenesisConfig}; +use client::genesis; /// Parse command line arguments and start the node. /// @@ -83,7 +83,7 @@ pub fn run(args: I) -> error::Result<()> where storage = genesis_config.genesis_map(); let block = genesis::construct_genesis_block(&storage); storage.extend(additional_storage_with_genesis(&block)); - (primitives::block::Header::decode(&mut block.header.to_vec().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect()) + (primitives::block::Header::decode(&mut block.header.encode().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect()) }; let client = client::new_in_mem(executor, prepare_genesis)?; diff --git a/polkadot/executor/Cargo.toml b/polkadot/executor/Cargo.toml index 2c268ad51db88..60cd4ee20d6b9 100644 --- a/polkadot/executor/Cargo.toml +++ b/polkadot/executor/Cargo.toml @@ -10,6 +10,7 @@ triehash = { version = "0.1" } ed25519 = { path = "../../substrate/ed25519" } substrate-codec = { path = "../../substrate/codec" } substrate-runtime-io = { path = "../../substrate/runtime-io" } +substrate-runtime-support = { path = "../../substrate/runtime-support" } substrate-state-machine = { path = "../../substrate/state-machine" } substrate-executor = { path = "../../substrate/executor" } substrate-primitives = { path = "../../substrate/primitives" } diff --git a/polkadot/executor/src/lib.rs b/polkadot/executor/src/lib.rs index f4d5af026f55d..7db96440a4608 100644 --- a/polkadot/executor/src/lib.rs +++ b/polkadot/executor/src/lib.rs @@ -26,9 +26,9 @@ extern crate substrate_primitives as primitives; extern crate polkadot_primitives as polkadot_primitives; extern crate ed25519; extern crate triehash; -#[cfg(test)] -#[macro_use] -extern crate hex_literal; + +#[cfg(test)] extern crate substrate_runtime_support as runtime_support; +#[cfg(test)] #[macro_use] extern crate hex_literal; use polkadot_runtime as runtime; use substrate_executor::error::{Error, ErrorKind}; @@ -62,7 +62,7 @@ mod tests { use super::*; use substrate_executor::WasmExecutor; use codec::{KeyedVec, Slicable, Joiner}; - use polkadot_runtime::support::{one, two, Hashable}; + use runtime_support::{one, two, Hashable}; use polkadot_runtime::runtime::staking::balance; use state_machine::{CodeExecutor, TestExternalities}; use primitives::twox_128; @@ -87,7 +87,7 @@ mod tests { function: Function::StakingTransfer(two(), 69), }; let signature = secret_for(&transaction.signed).unwrap() - .sign(&transaction.to_vec()); + .sign(&transaction.encode()); UncheckedTransaction { transaction, signature } } @@ -99,7 +99,7 @@ mod tests { twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0] ], }; - let r = executor().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].join(&Header::from_block_number(1u64)).join(&tx())); + let r = executor().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); assert!(r.is_err()); } @@ -110,7 +110,7 @@ mod tests { twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0] ], }; - let r = executor().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].join(&Header::from_block_number(1u64)).join(&tx())); + let r = executor().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); assert!(r.is_err()); } @@ -123,7 +123,7 @@ mod tests { twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ], }; - let r = executor().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].join(&Header::from_block_number(1u64)).join(&tx())); + let r = executor().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); assert!(r.is_ok()); runtime_io::with_externalities(&mut t, || { @@ -141,7 +141,7 @@ mod tests { twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ], }; - let r = executor().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].join(&Header::from_block_number(1u64)).join(&tx())); + let r = executor().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); assert!(r.is_ok()); runtime_io::with_externalities(&mut t, || { @@ -156,20 +156,20 @@ mod tests { let three = [3u8; 32]; TestExternalities { storage: map![ - twox_128(&0u64.to_keyed_vec(b"sys:old:")).to_vec() => [69u8; 32].to_vec(), - twox_128(b"gov:apr").to_vec() => vec![].join(&667u32), - twox_128(b"ses:len").to_vec() => vec![].join(&2u64), - twox_128(b"ses:val:len").to_vec() => vec![].join(&3u32), + twox_128(&0u64.to_keyed_vec(b"sys:old:")).to_vec() => [69u8; 32].encode(), + twox_128(b"gov:apr").to_vec() => vec![].and(&667u32), + twox_128(b"ses:len").to_vec() => vec![].and(&2u64), + twox_128(b"ses:val:len").to_vec() => vec![].and(&3u32), twox_128(&0u32.to_keyed_vec(b"ses:val:")).to_vec() => one.to_vec(), twox_128(&1u32.to_keyed_vec(b"ses:val:")).to_vec() => two.to_vec(), twox_128(&2u32.to_keyed_vec(b"ses:val:")).to_vec() => three.to_vec(), - twox_128(b"sta:wil:len").to_vec() => vec![].join(&3u32), + twox_128(b"sta:wil:len").to_vec() => vec![].and(&3u32), twox_128(&0u32.to_keyed_vec(b"sta:wil:")).to_vec() => one.to_vec(), twox_128(&1u32.to_keyed_vec(b"sta:wil:")).to_vec() => two.to_vec(), twox_128(&2u32.to_keyed_vec(b"sta:wil:")).to_vec() => three.to_vec(), - twox_128(b"sta:spe").to_vec() => vec![].join(&2u64), - twox_128(b"sta:vac").to_vec() => vec![].join(&3u64), - twox_128(b"sta:era").to_vec() => vec![].join(&0u64), + twox_128(b"sta:spe").to_vec() => vec![].and(&2u64), + twox_128(b"sta:vac").to_vec() => vec![].and(&3u64), + twox_128(b"sta:era").to_vec() => vec![].and(&0u64), twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ], } } @@ -187,12 +187,12 @@ mod tests { let transactions = txs.into_iter().map(|transaction| { let signature = secret_for(&transaction.signed).unwrap() - .sign(&transaction.to_vec()); + .sign(&transaction.encode()); UncheckedTransaction { transaction, signature } }).collect::>(); - let transaction_root = ordered_trie_root(transactions.iter().map(Slicable::to_vec)).0.into(); + let transaction_root = ordered_trie_root(transactions.iter().map(Slicable::encode)).0.into(); let header = Header { parent_hash, @@ -203,7 +203,7 @@ mod tests { }; let hash = header.blake2_256(); - (Block { header, transactions }.to_vec(), hash.into()) + (Block { header, transactions }.encode(), hash.into()) } fn block1() -> (Vec, Hash) { @@ -285,7 +285,7 @@ mod tests { ], }; let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm"); - let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &vec![].join(&Header::from_block_number(1u64)).join(&tx())); + let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); assert!(r.is_err()); } @@ -299,7 +299,7 @@ mod tests { ], }; let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm"); - let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &vec![].join(&Header::from_block_number(1u64)).join(&tx())); + let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); assert!(r.is_ok()); runtime_io::with_externalities(&mut t, || { diff --git a/polkadot/primitives/src/block.rs b/polkadot/primitives/src/block.rs index 489411351759b..d71fa82e1c287 100644 --- a/polkadot/primitives/src/block.rs +++ b/polkadot/primitives/src/block.rs @@ -42,8 +42,8 @@ impl Slicable for Log { Vec::::decode(input).map(Log) } - fn as_slice_then R>(&self, f: F) -> R { - self.0.as_slice_then(f) + fn using_encoded R>(&self, f: F) -> R { + self.0.using_encoded(f) } } @@ -62,8 +62,8 @@ impl Slicable for Digest { Vec::::decode(input).map(|logs| Digest { logs }) } - fn as_slice_then R>(&self, f: F) -> R { - self.logs.as_slice_then(f) + fn using_encoded R>(&self, f: F) -> R { + self.logs.using_encoded(f) } } @@ -86,18 +86,14 @@ impl Slicable for Block { Some(Block { header, transactions }) } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let mut v = Vec::new(); - v.extend(self.header.to_vec()); - v.extend(self.transactions.to_vec()); + v.extend(self.header.encode()); + v.extend(self.transactions.encode()); v } - - fn as_slice_then R>(&self, f: F) -> R { - f(self.to_vec().as_slice()) - } } /// A relay chain block header. @@ -144,21 +140,17 @@ impl Slicable for Header { }) } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let mut v = Vec::new(); - self.parent_hash.as_slice_then(|s| v.extend(s)); - self.number.as_slice_then(|s| v.extend(s)); - self.state_root.as_slice_then(|s| v.extend(s)); - self.transaction_root.as_slice_then(|s| v.extend(s)); - self.digest.as_slice_then(|s| v.extend(s)); + self.parent_hash.using_encoded(|s| v.extend(s)); + self.number.using_encoded(|s| v.extend(s)); + self.state_root.using_encoded(|s| v.extend(s)); + self.transaction_root.using_encoded(|s| v.extend(s)); + self.digest.using_encoded(|s| v.extend(s)); v } - - fn as_slice_then R>(&self, f: F) -> R { - f(self.to_vec().as_slice()) - } } #[cfg(test)] @@ -189,7 +181,7 @@ mod tests { } }"#); - let v = header.to_vec(); + let v = header.encode(); assert_eq!(Header::decode(&mut &v[..]).unwrap(), header); } } diff --git a/polkadot/primitives/src/parachain.rs b/polkadot/primitives/src/parachain.rs index 6535e0f0e04f1..0f4c4adefc1bc 100644 --- a/polkadot/primitives/src/parachain.rs +++ b/polkadot/primitives/src/parachain.rs @@ -40,8 +40,8 @@ impl Slicable for Id { u32::decode(input).map(Id) } - fn as_slice_then R>(&self, f: F) -> R { - self.0.as_slice_then(f) + fn using_encoded R>(&self, f: F) -> R { + self.0.using_encoded(f) } } @@ -66,21 +66,21 @@ impl Slicable for Chain { } } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let mut v = Vec::new(); match *self { - Chain::Relay => { 0u8.as_slice_then(|s| v.extend(s)); } + Chain::Relay => { 0u8.using_encoded(|s| v.extend(s)); } Chain::Parachain(id) => { - 1u8.as_slice_then(|s| v.extend(s)); - id.as_slice_then(|s| v.extend(s)); + 1u8.using_encoded(|s| v.extend(s)); + id.using_encoded(|s| v.extend(s)); } } v } - fn as_slice_then R>(&self, f: F) -> R { - f(&self.to_vec().as_slice()) + fn using_encoded R>(&self, f: F) -> R { + f(&self.encode().as_slice()) } } @@ -105,17 +105,17 @@ impl Slicable for DutyRoster { }) } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let mut v = Vec::new(); - v.extend(self.validator_duty.to_vec()); - v.extend(self.guarantor_duty.to_vec()); + v.extend(self.validator_duty.encode()); + v.extend(self.guarantor_duty.encode()); v } - fn as_slice_then R>(&self, f: F) -> R { - f(&self.to_vec().as_slice()) + fn using_encoded R>(&self, f: F) -> R { + f(&self.encode().as_slice()) } } @@ -204,8 +204,8 @@ impl Slicable for Activity { Vec::::decode(input).map(Activity) } - fn as_slice_then R>(&self, f: F) -> R { - self.0.as_slice_then(f) + fn using_encoded R>(&self, f: F) -> R { + self.0.using_encoded(f) } } diff --git a/polkadot/primitives/src/transaction.rs b/polkadot/primitives/src/transaction.rs index 0a68256f744d7..24a3ae4ee3634 100644 --- a/polkadot/primitives/src/transaction.rs +++ b/polkadot/primitives/src/transaction.rs @@ -113,47 +113,43 @@ impl Slicable for Proposal { Some(function) } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let mut v = Vec::new(); match *self { Proposal::SystemSetCode(ref data) => { - (InternalFunctionId::SystemSetCode as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (InternalFunctionId::SystemSetCode as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } Proposal::SessionSetLength(ref data) => { - (InternalFunctionId::SessionSetLength as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (InternalFunctionId::SessionSetLength as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } Proposal::SessionForceNewSession => { - (InternalFunctionId::SessionForceNewSession as u8).as_slice_then(|s| v.extend(s)); + (InternalFunctionId::SessionForceNewSession as u8).using_encoded(|s| v.extend(s)); } Proposal::StakingSetSessionsPerEra(ref data) => { - (InternalFunctionId::StakingSetSessionsPerEra as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (InternalFunctionId::StakingSetSessionsPerEra as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } Proposal::StakingSetBondingDuration(ref data) => { - (InternalFunctionId::StakingSetBondingDuration as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (InternalFunctionId::StakingSetBondingDuration as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } Proposal::StakingSetValidatorCount(ref data) => { - (InternalFunctionId::StakingSetValidatorCount as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (InternalFunctionId::StakingSetValidatorCount as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } Proposal::StakingForceNewEra => { - (InternalFunctionId::StakingForceNewEra as u8).as_slice_then(|s| v.extend(s)); + (InternalFunctionId::StakingForceNewEra as u8).using_encoded(|s| v.extend(s)); } Proposal::GovernanceSetApprovalPpmRequired(ref data) => { - (InternalFunctionId::GovernanceSetApprovalPpmRequired as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (InternalFunctionId::GovernanceSetApprovalPpmRequired as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } } v } - - fn as_slice_then R>(&self, f: F) -> R { - f(self.to_vec().as_slice()) - } } @@ -232,43 +228,43 @@ impl Slicable for Function { }) } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let mut v = Vec::new(); match *self { Function::TimestampSet(ref data) => { - (FunctionId::TimestampSet as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (FunctionId::TimestampSet as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } Function::SessionSetKey(ref data) => { - (FunctionId::SessionSetKey as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (FunctionId::SessionSetKey as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } Function::StakingStake => { - (FunctionId::StakingStake as u8).as_slice_then(|s| v.extend(s)); + (FunctionId::StakingStake as u8).using_encoded(|s| v.extend(s)); } Function::StakingUnstake => { - (FunctionId::StakingUnstake as u8).as_slice_then(|s| v.extend(s)); + (FunctionId::StakingUnstake as u8).using_encoded(|s| v.extend(s)); } Function::StakingTransfer(ref to, ref amount) => { - (FunctionId::StakingTransfer as u8).as_slice_then(|s| v.extend(s)); - to.as_slice_then(|s| v.extend(s)); - amount.as_slice_then(|s| v.extend(s)); + (FunctionId::StakingTransfer as u8).using_encoded(|s| v.extend(s)); + to.using_encoded(|s| v.extend(s)); + amount.using_encoded(|s| v.extend(s)); } Function::GovernancePropose(ref data) => { - (FunctionId::GovernancePropose as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (FunctionId::GovernancePropose as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } Function::GovernanceApprove(ref data) => { - (FunctionId::GovernanceApprove as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (FunctionId::GovernanceApprove as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } } v } - fn as_slice_then R>(&self, f: F) -> R { - f(self.to_vec().as_slice()) + fn using_encoded R>(&self, f: F) -> R { + f(self.encode().as_slice()) } } @@ -293,19 +289,15 @@ impl Slicable for Transaction { }) } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let mut v = Vec::new(); - self.signed.as_slice_then(|s| v.extend(s)); - self.nonce.as_slice_then(|s| v.extend(s)); - self.function.as_slice_then(|s| v.extend(s)); + self.signed.using_encoded(|s| v.extend(s)); + self.nonce.using_encoded(|s| v.extend(s)); + self.function.using_encoded(|s| v.extend(s)); v } - - fn as_slice_then R>(&self, f: F) -> R { - f(self.to_vec().as_slice()) - } } impl ::codec::NonTrivialSlicable for Transaction {} @@ -334,27 +326,23 @@ impl Slicable for UncheckedTransaction { }) } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let mut v = Vec::new(); // need to prefix with the total length as u32 to ensure it's binary comptible with // Vec. we'll make room for it here, then overwrite once we know the length. v.extend(&[0u8; 4]); - self.transaction.signed.as_slice_then(|s| v.extend(s)); - self.transaction.nonce.as_slice_then(|s| v.extend(s)); - self.transaction.function.as_slice_then(|s| v.extend(s)); - self.signature.as_slice_then(|s| v.extend(s)); + self.transaction.signed.using_encoded(|s| v.extend(s)); + self.transaction.nonce.using_encoded(|s| v.extend(s)); + self.transaction.function.using_encoded(|s| v.extend(s)); + self.signature.using_encoded(|s| v.extend(s)); let length = (v.len() - 4) as u32; - length.as_slice_then(|s| v[0..4].copy_from_slice(s)); + length.using_encoded(|s| v[0..4].copy_from_slice(s)); v } - - fn as_slice_then R>(&self, f: F) -> R { - f(self.to_vec().as_slice()) - } } impl ::codec::NonTrivialSlicable for UncheckedTransaction {} @@ -396,7 +384,7 @@ mod tests { // df0f0200 // 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - let v = Slicable::to_vec(&tx); + let v = Slicable::encode(&tx); println!("{}", HexDisplay::from(&v)); assert_eq!(UncheckedTransaction::decode(&mut &v[..]).unwrap(), tx); } diff --git a/polkadot/runtime/Cargo.toml b/polkadot/runtime/Cargo.toml index d3b3cfb34f05c..c8decd0462d2d 100644 --- a/polkadot/runtime/Cargo.toml +++ b/polkadot/runtime/Cargo.toml @@ -10,6 +10,7 @@ log = { version = "0.3", optional = true } substrate-codec = { path = "../../substrate/codec" } substrate-runtime-std = { path = "../../substrate/runtime-std" } substrate-runtime-io = { path = "../../substrate/runtime-io" } +substrate-runtime-support = { path = "../../substrate/runtime-support" } substrate-primitives = { path = "../../substrate/primitives" } polkadot-primitives = { path = "../primitives" } @@ -19,6 +20,7 @@ std = [ "substrate-codec/std", "substrate-runtime-std/std", "substrate-runtime-io/std", + "substrate-runtime-support/std", "substrate-primitives/std", "polkadot-primitives/std", "log" diff --git a/polkadot/runtime/src/support/environment.rs b/polkadot/runtime/src/environment.rs similarity index 100% rename from polkadot/runtime/src/support/environment.rs rename to polkadot/runtime/src/environment.rs diff --git a/polkadot/runtime/src/genesismap.rs b/polkadot/runtime/src/genesismap.rs index 7cb0aba5b63ea..4100f411b0d31 100644 --- a/polkadot/runtime/src/genesismap.rs +++ b/polkadot/runtime/src/genesismap.rs @@ -17,11 +17,12 @@ //! Tool for creating the genesis block. use codec::{KeyedVec, Joiner}; -use polkadot_primitives::{BlockNumber, Block, AccountId}; use std::collections::HashMap; use runtime_io::twox_128; +use runtime_support::Hashable; +use primitives::Block; +use polkadot_primitives::{BlockNumber, AccountId}; use runtime::staking::Balance; -use support::Hashable; /// Configuration of a general Polkadot genesis block. pub struct GenesisConfig { @@ -52,32 +53,32 @@ impl GenesisConfig { pub fn genesis_map(&self) -> HashMap, Vec> { let wasm_runtime = include_bytes!("../wasm/genesis.wasm").to_vec(); vec![ - (&b"gov:apr"[..], vec![].join(&self.approval_ratio)), - (&b"ses:len"[..], vec![].join(&self.session_length)), - (&b"ses:val:len"[..], vec![].join(&(self.validators.len() as u32))), - (&b"sta:wil:len"[..], vec![].join(&0u32)), - (&b"sta:spe"[..], vec![].join(&self.sessions_per_era)), - (&b"sta:vac"[..], vec![].join(&(self.validators.len() as u32))), - (&b"sta:era"[..], vec![].join(&0u64)), + (&b"gov:apr"[..], vec![].and(&self.approval_ratio)), + (&b"ses:len"[..], vec![].and(&self.session_length)), + (&b"ses:val:len"[..], vec![].and(&(self.validators.len() as u32))), + (&b"sta:wil:len"[..], vec![].and(&0u32)), + (&b"sta:spe"[..], vec![].and(&self.sessions_per_era)), + (&b"sta:vac"[..], vec![].and(&(self.validators.len() as u32))), + (&b"sta:era"[..], vec![].and(&0u64)), ].into_iter() .map(|(k, v)| (k.into(), v)) .chain(self.validators.iter() .enumerate() - .map(|(i, account)| ((i as u32).to_keyed_vec(b"ses:val:"), vec![].join(account))) + .map(|(i, account)| ((i as u32).to_keyed_vec(b"ses:val:"), vec![].and(account))) ).chain(self.authorities.iter() .enumerate() - .map(|(i, account)| ((i as u32).to_keyed_vec(b":auth:"), vec![].join(account))) + .map(|(i, account)| ((i as u32).to_keyed_vec(b":auth:"), vec![].and(account))) ).chain(self.balances.iter() - .map(|&(account, balance)| (account.to_keyed_vec(b"sta:bal:"), vec![].join(&balance))) + .map(|&(account, balance)| (account.to_keyed_vec(b"sta:bal:"), vec![].and(&balance))) ) .map(|(k, v)| (twox_128(&k[..])[..].to_vec(), v.to_vec())) .chain(vec![ (b":code"[..].into(), wasm_runtime), - (b":auth:len"[..].into(), vec![].join(&(self.authorities.len() as u32))), + (b":auth:len"[..].into(), vec![].and(&(self.authorities.len() as u32))), ].into_iter()) .chain(self.authorities.iter() .enumerate() - .map(|(i, account)| ((i as u32).to_keyed_vec(b":auth:"), vec![].join(account))) + .map(|(i, account)| ((i as u32).to_keyed_vec(b":auth:"), vec![].and(account))) ) .collect() } @@ -86,6 +87,6 @@ impl GenesisConfig { pub fn additional_storage_with_genesis(genesis_block: &Block) -> HashMap, Vec> { use codec::Slicable; map![ - twox_128(&0u64.to_keyed_vec(b"sys:old:")).to_vec() => genesis_block.header.blake2_256().to_vec() + twox_128(&0u64.to_keyed_vec(b"sys:old:")).to_vec() => genesis_block.header.blake2_256().encode() ] } diff --git a/polkadot/runtime/src/lib.rs b/polkadot/runtime/src/lib.rs index 10d37aacaeadc..6eb3a259fe7b7 100644 --- a/polkadot/runtime/src/lib.rs +++ b/polkadot/runtime/src/lib.rs @@ -19,28 +19,22 @@ #![cfg_attr(not(feature = "std"), no_std)] extern crate substrate_runtime_std as rstd; +#[macro_use] extern crate substrate_runtime_io as runtime_io; +extern crate substrate_runtime_support as runtime_support; -#[macro_use] -extern crate substrate_runtime_io as runtime_io; - -#[cfg(feature = "std")] -extern crate rustc_hex; +#[cfg(feature = "std")] extern crate rustc_hex; extern crate substrate_codec as codec; -extern crate substrate_primitives; +#[cfg(feature = "std")] #[macro_use] extern crate substrate_primitives as primitives; extern crate polkadot_primitives; -#[cfg(test)] -#[macro_use] -extern crate hex_literal; +#[cfg(test)] #[macro_use] extern crate hex_literal; -#[macro_use] -pub mod support; +pub mod environment; pub mod runtime; pub mod api; -#[cfg(feature = "std")] -pub mod genesismap; +#[cfg(feature = "std")] pub mod genesismap; /// Type definitions and helpers for transactions. pub mod transaction { @@ -72,7 +66,7 @@ pub mod transaction { /// /// On failure, return the transaction back. pub fn check(tx: UncheckedTransaction) -> Result { - let msg = ::codec::Slicable::to_vec(&tx.transaction); + let msg = ::codec::Slicable::encode(&tx.transaction); if ::runtime_io::ed25519_verify(&tx.signature.0, &msg, &tx.transaction.signed) { Ok(CheckedTransaction(tx)) } else { diff --git a/polkadot/runtime/src/runtime/consensus.rs b/polkadot/runtime/src/runtime/consensus.rs index bbc62eeba0750..7d50f6abd418f 100644 --- a/polkadot/runtime/src/runtime/consensus.rs +++ b/polkadot/runtime/src/runtime/consensus.rs @@ -17,7 +17,7 @@ //! Conensus module for runtime; manages the authority set ready for the native code. use rstd::prelude::*; -use support::storage::unhashed::StorageVec; +use runtime_support::storage::unhashed::StorageVec; use polkadot_primitives::SessionKey; struct AuthorityStorageVec {} diff --git a/polkadot/runtime/src/runtime/governance.rs b/polkadot/runtime/src/runtime/governance.rs index a7d2baf6778b1..4ac1e17a3398e 100644 --- a/polkadot/runtime/src/runtime/governance.rs +++ b/polkadot/runtime/src/runtime/governance.rs @@ -27,7 +27,7 @@ use rstd::prelude::*; use codec::KeyedVec; -use support::storage; +use runtime_support::storage; use polkadot_primitives::{Proposal, AccountId, Hash, BlockNumber}; use runtime::{staking, system, session}; @@ -147,7 +147,8 @@ mod tests { use super::*; use runtime_io::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; - use support::{one, two, with_env}; + use runtime_support::{one, two}; + use environment::with_env; use polkadot_primitives::{AccountId, Proposal}; use runtime::{staking, session}; @@ -157,19 +158,19 @@ mod tests { let three = [3u8; 32]; TestExternalities { storage: map![ - twox_128(APPROVALS_REQUIRED).to_vec() => vec![].join(&667u32), - twox_128(b"ses:len").to_vec() => vec![].join(&1u64), - twox_128(b"ses:val:len").to_vec() => vec![].join(&3u32), + twox_128(APPROVALS_REQUIRED).to_vec() => vec![].and(&667u32), + twox_128(b"ses:len").to_vec() => vec![].and(&1u64), + twox_128(b"ses:val:len").to_vec() => vec![].and(&3u32), twox_128(&0u32.to_keyed_vec(b"ses:val:")).to_vec() => one.to_vec(), twox_128(&1u32.to_keyed_vec(b"ses:val:")).to_vec() => two.to_vec(), twox_128(&2u32.to_keyed_vec(b"ses:val:")).to_vec() => three.to_vec(), - twox_128(b"sta:wil:len").to_vec() => vec![].join(&3u32), + twox_128(b"sta:wil:len").to_vec() => vec![].and(&3u32), twox_128(&0u32.to_keyed_vec(b"sta:wil:")).to_vec() => one.to_vec(), twox_128(&1u32.to_keyed_vec(b"sta:wil:")).to_vec() => two.to_vec(), twox_128(&2u32.to_keyed_vec(b"sta:wil:")).to_vec() => three.to_vec(), - twox_128(b"sta:spe").to_vec() => vec![].join(&1u64), - twox_128(b"sta:vac").to_vec() => vec![].join(&3u64), - twox_128(b"sta:era").to_vec() => vec![].join(&1u64) + twox_128(b"sta:spe").to_vec() => vec![].and(&1u64), + twox_128(b"sta:vac").to_vec() => vec![].and(&3u64), + twox_128(b"sta:era").to_vec() => vec![].and(&1u64) ], } } diff --git a/polkadot/runtime/src/runtime/parachains.rs b/polkadot/runtime/src/runtime/parachains.rs index c039892c03bfc..56559ee356692 100644 --- a/polkadot/runtime/src/runtime/parachains.rs +++ b/polkadot/runtime/src/runtime/parachains.rs @@ -18,8 +18,9 @@ use rstd::prelude::*; use codec::{Slicable, Joiner}; +use runtime_support::{Hashable, storage}; +use environment::with_env; use runtime::session; -use support::{Hashable, with_env, storage}; use polkadot_primitives::parachain::{Id, Chain, DutyRoster}; const PARACHAIN_COUNT: &[u8] = b"par:cou"; @@ -43,7 +44,7 @@ pub fn calculate_duty_roster() -> DutyRoster { let mut roles_gua = roles_val.clone(); let h = with_env(|e| e.parent_hash.clone()); - let mut seed = Vec::::new().join(&h).join(b"validator_role_pairs").blake2_256(); + let mut seed = Vec::::new().and(&h).and(b"validator_role_pairs").blake2_256(); // shuffle for i in 0..(validator_count - 1) { @@ -78,13 +79,13 @@ mod tests { use super::*; use runtime_io::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; - use support::{one, two, with_env}; + use runtime_support::{one, two}; use runtime::{consensus, session}; fn simple_setup() -> TestExternalities { TestExternalities { storage: map![ - twox_128(b"ses:val:len").to_vec() => vec![].join(&8u32), - twox_128(b"par:cou").to_vec() => vec![].join(&2u32) + twox_128(b"ses:val:len").to_vec() => vec![].and(&8u32), + twox_128(b"par:cou").to_vec() => vec![].and(&2u32) ], } } diff --git a/polkadot/runtime/src/runtime/session.rs b/polkadot/runtime/src/runtime/session.rs index 56a12f05c085c..9252e9774d5db 100644 --- a/polkadot/runtime/src/runtime/session.rs +++ b/polkadot/runtime/src/runtime/session.rs @@ -19,7 +19,7 @@ use rstd::prelude::*; use codec::KeyedVec; -use support::{storage, StorageVec}; +use runtime_support::{storage, StorageVec}; use polkadot_primitives::{AccountId, SessionKey, BlockNumber}; use runtime::{system, staking, consensus}; @@ -139,19 +139,20 @@ mod tests { use super::internal::*; use runtime_io::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; - use support::{one, two, with_env}; + use runtime_support::{one, two}; + use environment::with_env; use polkadot_primitives::AccountId; use runtime::{consensus, session}; fn simple_setup() -> TestExternalities { TestExternalities { storage: map![ - twox_128(SESSION_LENGTH).to_vec() => vec![].join(&2u64), + twox_128(SESSION_LENGTH).to_vec() => vec![].and(&2u64), // the validators (10, 20, ...) - twox_128(b"ses:val:len").to_vec() => vec![].join(&2u32), + twox_128(b"ses:val:len").to_vec() => vec![].and(&2u32), twox_128(&0u32.to_keyed_vec(ValidatorStorageVec::PREFIX)).to_vec() => vec![10; 32], twox_128(&1u32.to_keyed_vec(ValidatorStorageVec::PREFIX)).to_vec() => vec![20; 32], // initial session keys (11, 21, ...) - b":auth:len".to_vec() => vec![].join(&2u32), + b":auth:len".to_vec() => vec![].and(&2u32), 0u32.to_keyed_vec(b":auth:") => vec![11; 32], 1u32.to_keyed_vec(b":auth:") => vec![21; 32] ], } diff --git a/polkadot/runtime/src/runtime/staking.rs b/polkadot/runtime/src/runtime/staking.rs index 210c518146b37..b281bc5cd50e0 100644 --- a/polkadot/runtime/src/runtime/staking.rs +++ b/polkadot/runtime/src/runtime/staking.rs @@ -20,7 +20,7 @@ use rstd::prelude::*; use rstd::cell::RefCell; use runtime_io::print; use codec::KeyedVec; -use support::{storage, StorageVec}; +use runtime_support::{storage, StorageVec}; use polkadot_primitives::{BlockNumber, AccountId}; use runtime::{system, session, governance}; @@ -215,7 +215,8 @@ mod tests { use runtime_io::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; - use support::{one, two, with_env}; + use runtime_support::{one, two}; + use environment::with_env; use polkadot_primitives::AccountId; use runtime::{staking, session}; @@ -227,17 +228,17 @@ mod tests { let four = [4u8; 32]; let mut t = TestExternalities { storage: map![ - twox_128(b"ses:len").to_vec() => vec![].join(&1u64), - twox_128(b"ses:val:len").to_vec() => vec![].join(&2u32), + twox_128(b"ses:len").to_vec() => vec![].and(&1u64), + twox_128(b"ses:val:len").to_vec() => vec![].and(&2u32), twox_128(&0u32.to_keyed_vec(b"ses:val:")).to_vec() => vec![10; 32], twox_128(&1u32.to_keyed_vec(b"ses:val:")).to_vec() => vec![20; 32], - twox_128(SESSIONS_PER_ERA).to_vec() => vec![].join(&2u64), - twox_128(VALIDATOR_COUNT).to_vec() => vec![].join(&2u32), - twox_128(BONDING_DURATION).to_vec() => vec![].join(&3u64), - twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].join(&10u64), - twox_128(&two.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].join(&20u64), - twox_128(&three.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].join(&30u64), - twox_128(&four.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].join(&40u64) + twox_128(SESSIONS_PER_ERA).to_vec() => vec![].and(&2u64), + twox_128(VALIDATOR_COUNT).to_vec() => vec![].and(&2u32), + twox_128(BONDING_DURATION).to_vec() => vec![].and(&3u64), + twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&10u64), + twox_128(&two.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&20u64), + twox_128(&three.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&30u64), + twox_128(&four.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&40u64) ], }; with_externalities(&mut t, || { @@ -296,8 +297,8 @@ mod tests { #[test] fn staking_eras_work() { let mut t = TestExternalities { storage: map![ - twox_128(b"ses:len").to_vec() => vec![].join(&1u64), - twox_128(SESSIONS_PER_ERA).to_vec() => vec![].join(&2u64) + twox_128(b"ses:len").to_vec() => vec![].and(&1u64), + twox_128(SESSIONS_PER_ERA).to_vec() => vec![].and(&2u64) ], }; with_externalities(&mut t, || { assert_eq!(era_length(), 2u64); @@ -363,7 +364,7 @@ mod tests { let two = two(); let mut t = TestExternalities { storage: map![ - twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].join(&42u64) + twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&42u64) ], }; with_externalities(&mut t, || { @@ -378,7 +379,7 @@ mod tests { let two = two(); let mut t = TestExternalities { storage: map![ - twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].join(&111u64) + twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&111u64) ], }; with_externalities(&mut t, || { @@ -395,7 +396,7 @@ mod tests { let two = two(); let mut t = TestExternalities { storage: map![ - twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].join(&111u64) + twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&111u64) ], }; with_externalities(&mut t, || { diff --git a/polkadot/runtime/src/runtime/system.rs b/polkadot/runtime/src/runtime/system.rs index a82d911ea92c5..2a8519a6832d0 100644 --- a/polkadot/runtime/src/runtime/system.rs +++ b/polkadot/runtime/src/runtime/system.rs @@ -21,7 +21,8 @@ use rstd::prelude::*; use rstd::mem; use runtime_io::{print, storage_root, enumerated_trie_root}; use codec::{KeyedVec, Slicable}; -use support::{Hashable, storage, with_env}; +use runtime_support::{Hashable, storage}; +use environment::with_env; use polkadot_primitives::{AccountId, Hash, TxOrder, BlockNumber, Block, Header, UncheckedTransaction, Function, Log}; use runtime::{staking, session}; @@ -184,7 +185,7 @@ fn initial_checks(block: &Block) { ); // check transaction trie root represents the transactions. - let txs = block.transactions.iter().map(Slicable::to_vec).collect::>(); + let txs = block.transactions.iter().map(Slicable::encode).collect::>(); let txs = txs.iter().map(Vec::as_slice).collect::>(); let txs_root = enumerated_trie_root(&txs).into(); info_expect_equal_hash(&header.transaction_root, &txs_root); @@ -213,7 +214,7 @@ fn post_finalise(header: &Header) { #[cfg(feature = "std")] fn info_expect_equal_hash(given: &Hash, expected: &Hash) { - use support::HexDisplay; + use primitives::hexdisplay::HexDisplay; if given != expected { println!("Hash: given={}, expected={}", HexDisplay::from(&given.0), HexDisplay::from(&expected.0)); } @@ -235,7 +236,9 @@ mod tests { use runtime_io::{with_externalities, twox_128, TestExternalities}; use codec::{Joiner, KeyedVec, Slicable}; - use support::{StaticHexInto, HexDisplay, one, two}; + use runtime_support::{one, two}; + use environment::with_env; + use primitives::hexdisplay::HexDisplay; use polkadot_primitives::{Header, Digest, UncheckedTransaction, Transaction, Function}; use runtime::staking; @@ -254,7 +257,7 @@ mod tests { nonce: 0, function: Function::StakingTransfer(two, 69), }, - signature: "5f9832c5a4a39e2dd4a3a0c5b400e9836beb362cb8f7d845a8291a2ae6fe366612e080e4acd0b5a75c3d0b6ee69614a68fb63698c1e76bf1f2dcd8fa617ddf05".parse().unwrap(), + signature: hex!("5f9832c5a4a39e2dd4a3a0c5b400e9836beb362cb8f7d845a8291a2ae6fe366612e080e4acd0b5a75c3d0b6ee69614a68fb63698c1e76bf1f2dcd8fa617ddf05").into(), }; with_externalities(&mut t, || { @@ -270,20 +273,20 @@ mod tests { let three = [3u8; 32]; TestExternalities { storage: map![ - twox_128(&0u64.to_keyed_vec(b"sys:old:")).to_vec() => [69u8; 32].to_vec(), - twox_128(b"gov:apr").to_vec() => vec![].join(&667u32), - twox_128(b"ses:len").to_vec() => vec![].join(&2u64), - twox_128(b"ses:val:len").to_vec() => vec![].join(&3u32), + twox_128(&0u64.to_keyed_vec(b"sys:old:")).to_vec() => [69u8; 32].encode(), + twox_128(b"gov:apr").to_vec() => vec![].and(&667u32), + twox_128(b"ses:len").to_vec() => vec![].and(&2u64), + twox_128(b"ses:val:len").to_vec() => vec![].and(&3u32), twox_128(&0u32.to_keyed_vec(b"ses:val:")).to_vec() => one.to_vec(), twox_128(&1u32.to_keyed_vec(b"ses:val:")).to_vec() => two.to_vec(), twox_128(&2u32.to_keyed_vec(b"ses:val:")).to_vec() => three.to_vec(), - twox_128(b"sta:wil:len").to_vec() => vec![].join(&3u32), + twox_128(b"sta:wil:len").to_vec() => vec![].and(&3u32), twox_128(&0u32.to_keyed_vec(b"sta:wil:")).to_vec() => one.to_vec(), twox_128(&1u32.to_keyed_vec(b"sta:wil:")).to_vec() => two.to_vec(), twox_128(&2u32.to_keyed_vec(b"sta:wil:")).to_vec() => three.to_vec(), - twox_128(b"sta:spe").to_vec() => vec![].join(&2u64), - twox_128(b"sta:vac").to_vec() => vec![].join(&3u64), - twox_128(b"sta:era").to_vec() => vec![].join(&0u64), + twox_128(b"sta:spe").to_vec() => vec![].and(&2u64), + twox_128(b"sta:vac").to_vec() => vec![].and(&3u64), + twox_128(b"sta:era").to_vec() => vec![].and(&0u64), twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ], } } diff --git a/polkadot/runtime/src/runtime/timestamp.rs b/polkadot/runtime/src/runtime/timestamp.rs index 45ebdcbe70b20..c64a511ad0388 100644 --- a/polkadot/runtime/src/runtime/timestamp.rs +++ b/polkadot/runtime/src/runtime/timestamp.rs @@ -16,7 +16,7 @@ //! Timestamp manager: just handles the current timestamp. -use support::storage; +use runtime_support::storage; pub type Timestamp = u64; @@ -48,7 +48,7 @@ mod tests { #[test] fn timestamp_works() { let mut t = TestExternalities { storage: map![ - twox_128(CURRENT_TIMESTAMP).to_vec() => vec![].join(&42u64) + twox_128(CURRENT_TIMESTAMP).to_vec() => vec![].and(&42u64) ], }; with_externalities(&mut t, || { diff --git a/polkadot/runtime/src/support/statichex.rs b/polkadot/runtime/src/support/statichex.rs deleted file mode 100644 index b750a8ca10f58..0000000000000 --- a/polkadot/runtime/src/support/statichex.rs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2017 Parity Technologies (UK) Ltd. -// This file is part of Polkadot. - -// Polkadot is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Polkadot is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Polkadot. If not, see . - -//! Interpret a static string of hex as a desired type. - -use rustc_hex::FromHex; - -/// Trait to allow conversion from a static hex string to an instance. -pub trait StaticHexConversion: Sized { - /// Convert the static str into Self. Use just like `From::from`. - fn from_static_hex(hex: &'static str) -> Self; -} - -macro_rules! impl_sizes { - ( $( $t:expr ),* ) => { $( - impl StaticHexConversion for [u8; $t] { - fn from_static_hex(hex: &'static str) -> Self { - let mut r = [0u8; $t]; - r.copy_from_slice(&FromHex::from_hex(hex).unwrap()); - r - } - } - )* } -} - -impl StaticHexConversion for Vec { - fn from_static_hex(hex: &'static str) -> Self { - FromHex::from_hex(hex).unwrap() - } -} - -impl_sizes!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 451, 42, 43, 44, 45, 46, 47, 48, - 56, 64, 80, 96, 112, 128); - -/// Trait to allow converting from itself (only implemented for a static str) into some useful -/// type (which must implement `StaticHexConversion`). -pub trait StaticHexInto { - /// Convert self (i.e. a static str) into the appropriate type. Use just like `Into::into`. - fn convert(self) -> T; -} - -impl StaticHexInto for &'static str { - fn convert(self) -> T { - T::from_static_hex(self) - } -} diff --git a/polkadot/runtime/src/support/testing.rs b/polkadot/runtime/src/support/testing.rs deleted file mode 100644 index a230ded26ffb4..0000000000000 --- a/polkadot/runtime/src/support/testing.rs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2017 Parity Technologies (UK) Ltd. -// This file is part of Polkadot. - -// Polkadot is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Polkadot is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Polkadot. If not, see . - -//! Testing helpers. - -use polkadot_primitives::AccountId; -use super::statichex::StaticHexInto; - -#[macro_export] -macro_rules! map { - ($( $name:expr => $value:expr ),*) => ( - vec![ $( ( $name, $value ) ),* ].into_iter().collect() - ) -} - -/// One account (to which we know the secret key). -pub fn one() -> AccountId { - "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".convert() -} -/// Another account (secret key known). -pub fn two() -> AccountId { - "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".convert() -} - -/// Hex display, this time for no_std. See main codebase for documentation. -pub struct HexDisplay<'a>(&'a [u8]); - -impl<'a> HexDisplay<'a> { - /// See main codebase for documentation. - pub fn from(d: &'a AsBytesRef) -> Self { HexDisplay(d.as_bytes_ref()) } -} - -impl<'a> ::std::fmt::Display for HexDisplay<'a> { - fn fmt(&self, fmtr: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { - for byte in self.0 { - try!( fmtr.write_fmt(format_args!("{:02x}", byte))); - } - Ok(()) - } -} - -/// See main codebase for documentation. -pub trait AsBytesRef { - /// See main codebase for documentation. - fn as_bytes_ref(&self) -> &[u8]; -} - -impl AsBytesRef for [u8] { - fn as_bytes_ref(&self) -> &[u8] { &self } -} - -impl<'a> AsBytesRef for &'a[u8] { - fn as_bytes_ref(&self) -> &[u8] { self } -} - -impl AsBytesRef for Vec { - fn as_bytes_ref(&self) -> &[u8] { &self[..] } -} - -macro_rules! impl_non_endians { - ( $( $t:ty ),* ) => { $( - impl AsBytesRef for $t { - fn as_bytes_ref(&self) -> &[u8] { &self[..] } - } - )* } -} - -impl_non_endians!([u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8], - [u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40], - [u8; 48], [u8; 56], [u8; 64], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); diff --git a/polkadot/runtime/wasm/Cargo.lock b/polkadot/runtime/wasm/Cargo.lock index 506b138461be0..1ed330a400aca 100644 --- a/polkadot/runtime/wasm/Cargo.lock +++ b/polkadot/runtime/wasm/Cargo.lock @@ -395,6 +395,7 @@ dependencies = [ "substrate-primitives 0.1.0", "substrate-runtime-io 0.1.0", "substrate-runtime-std 0.1.0", + "substrate-runtime-support 0.1.0", ] [[package]] @@ -638,6 +639,19 @@ dependencies = [ "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "substrate-runtime-support" +version = "0.1.0" +dependencies = [ + "environmental 0.1.0", + "hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-codec 0.1.0", + "substrate-primitives 0.1.0", + "substrate-runtime-io 0.1.0", + "substrate-runtime-std 0.1.0", + "substrate-state-machine 0.1.0", +] + [[package]] name = "substrate-state-machine" version = "0.1.0" diff --git a/polkadot/runtime/wasm/Cargo.toml b/polkadot/runtime/wasm/Cargo.toml index 10bfbc330f6a4..2452ce9bd28e1 100644 --- a/polkadot/runtime/wasm/Cargo.toml +++ b/polkadot/runtime/wasm/Cargo.toml @@ -10,6 +10,7 @@ crate-type = ["cdylib"] substrate-codec = { path = "../../../substrate/codec", default-features = false } substrate-runtime-std = { path = "../../../substrate/runtime-std", default-features = false } substrate-runtime-io = { path = "../../../substrate/runtime-io", default-features = false } +substrate-runtime-support = { path = "../../../substrate/runtime-support", default-features = false } substrate-primitives = { path = "../../../substrate/primitives", default-features = false } polkadot-primitives = { path = "../../primitives", default-features = false } @@ -19,8 +20,9 @@ std = [ "substrate-codec/std", "substrate-runtime-io/std", "substrate-runtime-std/std", + "substrate-runtime-support/std", "substrate-primitives/std", - "polkadot-primitives/std" + "polkadot-primitives/std", ] [profile.release] diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm index 5418e0432c20b6e36fc79ff8ab4f65e793bcc78b..e56ad51f9a1de40b9ae8d68e0d63a9c4689d19d9 100644 GIT binary patch literal 75751 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 N*hI}z*B>Lp{{y#}|Hl9T literal 78040 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"] error-chain = "0.11" log = "0.3" parking_lot = "0.4" -substrate-primitives = { path = "../primitives", version = "0.1" } -substrate-state-machine = { path = "../state-machine", version = "0.1" } -substrate-serializer = { path = "../serializer" } -substrate-executor = { path = "../executor" } -substrate-codec = { path = "../codec", version = "0.1" } triehash = "0.1" hex-literal = "0.1" -ed25519 = { path = "../ed25519", version = "0.1" } +ed25519 = { path = "../ed25519" } +substrate-codec = { path = "../codec" } +substrate-executor = { path = "../executor" } +substrate-primitives = { path = "../primitives" } +substrate-runtime-support = { path = "../runtime-support" } +substrate-serializer = { path = "../serializer" } +substrate-state-machine = { path = "../state-machine" } +substrate-test-runtime = { path = "../test-runtime" } diff --git a/polkadot/cli/src/genesis.rs b/substrate/client/src/genesis.rs similarity index 53% rename from polkadot/cli/src/genesis.rs rename to substrate/client/src/genesis.rs index 5e82d9a507bab..ba4a30741b4aa 100644 --- a/polkadot/cli/src/genesis.rs +++ b/substrate/client/src/genesis.rs @@ -17,7 +17,7 @@ //! Tool for creating the genesis block. use std::collections::HashMap; -use polkadot_primitives::{Block, Header}; +use primitives::{Block, Header}; use triehash::trie_root; /// Create a genesis block, given the initial storage. @@ -40,16 +40,36 @@ pub fn construct_genesis_block(storage: &HashMap, Vec>) -> Block { mod tests { use super::*; use codec::{Slicable, Joiner}; - use polkadot_runtime::support::{one, two, Hashable}; - use polkadot_runtime::genesismap::{GenesisConfig, additional_storage_with_genesis}; - use state_machine::execute; - use state_machine::OverlayedChanges; + use runtime_support::{one, two, Hashable}; + use test_runtime::genesismap::{GenesisConfig, additional_storage_with_genesis}; + use executor::{NativeExecutionDispatch, NativeExecutor, WasmExecutor, with_native_environment, + error}; + use state_machine::{execute, Externalities, OverlayedChanges}; use state_machine::backend::InMemory; - use polkadot_executor::executor; - use polkadot_primitives::{AccountId, Hash, BlockNumber, Header, Digest, UncheckedTransaction, - Transaction, Function}; + use test_runtime::{self, AccountId, Hash, Block, BlockNumber, Header, Digest, Transaction, + UncheckedTransaction}; use ed25519::Pair; + /// A null struct which implements `NativeExecutionDispatch` feeding in the hard-coded runtime. + pub struct LocalNativeExecutionDispatch; + + impl NativeExecutionDispatch for LocalNativeExecutionDispatch { + fn native_equivalent() -> &'static [u8] { + // WARNING!!! This assumes that the runtime was built *before* the main project. Until we + // get a proper build script, this must be strictly adhered to or things will go wrong. + include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm") + } + + fn dispatch(ext: &mut Externalities, method: &str, data: &[u8]) -> error::Result> { + with_native_environment(ext, move || test_runtime::apis::dispatch(method, data))? + .ok_or_else(|| error::ErrorKind::MethodNotFound(method.to_owned()).into()) + } + } + + fn executor() -> NativeExecutor { + NativeExecutor { _dummy: Default::default() } + } + fn secret_for(who: &AccountId) -> Option { match who { x if *x == one() => Some(Pair::from_seed(b"12345678901234567890123456789012")), @@ -61,14 +81,14 @@ mod tests { fn construct_block(backend: &InMemory, number: BlockNumber, parent_hash: Hash, state_root: Hash, txs: Vec) -> (Vec, Hash) { use triehash::ordered_trie_root; - let transactions = txs.into_iter().map(|transaction| { - let signature = secret_for(&transaction.signed).unwrap() - .sign(&transaction.to_vec()); + let transactions = txs.into_iter().map(|tx| { + let signature = secret_for(&tx.from).unwrap() + .sign(&tx.encode()); - UncheckedTransaction { transaction, signature } + UncheckedTransaction { tx, signature } }).collect::>(); - let transaction_root = ordered_trie_root(transactions.iter().map(Slicable::to_vec)).0.into(); + let transaction_root = ordered_trie_root(transactions.iter().map(Slicable::encode)).0.into(); let mut header = Header { parent_hash, @@ -87,7 +107,7 @@ mod tests { &mut overlay, &executor(), "execute_transaction", - &vec![].join(&header).join(tx) + &vec![].and(&header).and(tx) ).unwrap(); header = Header::decode(&mut &ret_data[..]).unwrap(); } @@ -97,11 +117,11 @@ mod tests { &mut overlay, &executor(), "finalise_block", - &vec![].join(&header) + &vec![].and(&header) ).unwrap(); header = Header::decode(&mut &ret_data[..]).unwrap(); - (vec![].join(&Block { header, transactions }), hash.into()) + (vec![].and(&Block { header, transactions }), hash.into()) } fn block1(genesis_hash: Hash, backend: &InMemory) -> (Vec, Hash) { @@ -111,9 +131,10 @@ mod tests { genesis_hash, hex!("25e5b37074063ab75c889326246640729b40d0c86932edc527bc80db0e04fe5c").into(), vec![Transaction { - signed: one(), + from: one(), + to: two(), + amount: 69, nonce: 0, - function: Function::StakingTransfer(two(), 69), }] ) } @@ -139,4 +160,49 @@ mod tests { &b1data ).unwrap(); } + + #[test] + #[should_panic] + fn construct_genesis_with_bad_transaction_should_panic() { + let mut storage = GenesisConfig::new_simple( + vec![one(), two()], 68 + ).genesis_map(); + let block = construct_genesis_block(&storage); + let genesis_hash = block.header.blake2_256().into(); + storage.extend(additional_storage_with_genesis(&block).into_iter()); + + let mut overlay = OverlayedChanges::default(); + let backend = InMemory::from(storage); + let (b1data, _b1hash) = block1(genesis_hash, &backend); + + let _ = execute( + &backend, + &mut overlay, + &executor(), + "execute_block", + &b1data + ).unwrap(); + } + + #[test] + fn construct_genesis_should_work_under_wasm() { + let mut storage = GenesisConfig::new_simple( + vec![one(), two()], 1000 + ).genesis_map(); + let block = construct_genesis_block(&storage); + let genesis_hash = block.header.blake2_256().into(); + storage.extend(additional_storage_with_genesis(&block).into_iter()); + + let mut overlay = OverlayedChanges::default(); + let backend = InMemory::from(storage); + let (b1data, _b1hash) = block1(genesis_hash, &backend); + + let _ = execute( + &backend, + &mut overlay, + &WasmExecutor, + "execute_block", + &b1data + ).unwrap(); + } } diff --git a/substrate/client/src/in_mem.rs b/substrate/client/src/in_mem.rs index 0ed3499033af4..ce1aaf3db5d71 100644 --- a/substrate/client/src/in_mem.rs +++ b/substrate/client/src/in_mem.rs @@ -27,7 +27,7 @@ use primitives::block::{self, HeaderHash}; use blockchain::{self, BlockId, BlockStatus}; fn header_hash(header: &block::Header) -> block::HeaderHash { - primitives::hashing::blake2_256(&ser::to_vec(header)).into() + primitives::hashing::blake2_256(&ser::encode(header)).into() } struct PendingBlock { diff --git a/substrate/client/src/lib.rs b/substrate/client/src/lib.rs index 2db1455f7c8da..951eafbb26a76 100644 --- a/substrate/client/src/lib.rs +++ b/substrate/client/src/lib.rs @@ -22,11 +22,14 @@ extern crate substrate_primitives as primitives; extern crate substrate_state_machine as state_machine; extern crate substrate_serializer as ser; extern crate substrate_codec as codec; -extern crate substrate_executor; +extern crate substrate_executor as executor; extern crate ed25519; +#[cfg(test)] extern crate substrate_runtime_support as runtime_support; +#[cfg(test)] extern crate substrate_test_runtime as test_runtime; extern crate triehash; extern crate parking_lot; +#[cfg(test)] #[macro_use] extern crate hex_literal; #[macro_use] extern crate error_chain; #[macro_use] extern crate log; @@ -34,6 +37,7 @@ pub mod error; pub mod blockchain; pub mod backend; pub mod in_mem; +pub mod genesis; pub use blockchain::Info as ChainInfo; pub use blockchain::BlockId; diff --git a/substrate/codec/src/joiner.rs b/substrate/codec/src/joiner.rs index 7df97e570583d..dbe590f2bd03d 100644 --- a/substrate/codec/src/joiner.rs +++ b/substrate/codec/src/joiner.rs @@ -22,12 +22,12 @@ use super::slicable::Slicable; /// Trait to allow itself to be serialised into a value which can be extended /// by bytes. pub trait Joiner { - fn join(self, value: &V) -> Self; + fn and(self, value: &V) -> Self; } impl Joiner for T where T: for<'a> Extend<&'a u8> { - fn join(mut self, value: &V) -> Self { - value.as_slice_then(|s| self.extend(s)); + fn and(mut self, value: &V) -> Self { + value.using_encoded(|s| self.extend(s)); self } } diff --git a/substrate/codec/src/keyedvec.rs b/substrate/codec/src/keyedvec.rs index aac1df0f170d9..7a27ece90a274 100644 --- a/substrate/codec/src/keyedvec.rs +++ b/substrate/codec/src/keyedvec.rs @@ -41,7 +41,7 @@ macro_rules! impl_endians { ( $( $t:ty ),* ) => { $( impl KeyedVec for $t { fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec { - self.as_slice_then(|slice| { + self.using_encoded(|slice| { let mut r = prepend_key.to_vec(); r.extend(slice); r diff --git a/substrate/codec/src/slicable.rs b/substrate/codec/src/slicable.rs index 003e49c5f125e..fcce7806c1ad7 100644 --- a/substrate/codec/src/slicable.rs +++ b/substrate/codec/src/slicable.rs @@ -40,12 +40,16 @@ impl<'a> Input for &'a [u8] { pub trait Slicable: Sized { /// Attempt to deserialise the value from input. fn decode(value: &mut I) -> Option; + /// Convert self to an owned vector. - fn to_vec(&self) -> Vec { - self.as_slice_then(|s| s.to_vec()) + fn encode(&self) -> Vec { + self.using_encoded(|s| s.to_vec()) } + /// Convert self to a slice and then invoke the given closure with it. - fn as_slice_then R>(&self, f: F) -> R; + fn using_encoded R>(&self, f: F) -> R { + f(&self.encode()) + } } /// Trait to mark that a type is not trivially (essentially "in place") serialisable. @@ -67,7 +71,7 @@ impl Slicable for T { Some(val.from_le()) } - fn as_slice_then R>(&self, f: F) -> R { + fn using_encoded R>(&self, f: F) -> R { self.as_le_then(|le| { let size = mem::size_of::(); let value_slice = unsafe { @@ -96,15 +100,12 @@ impl Slicable for Vec { } }) } - fn as_slice_then R>(&self, f: F) -> R { - f(&self.to_vec()) - } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let len = self.len(); assert!(len <= u32::max_value() as usize, "Attempted to serialize vec with too many elements."); - let mut r: Vec = Vec::new().join(&(len as u32)); + let mut r: Vec = Vec::new().and(&(len as u32)); r.extend_from_slice(self); r } @@ -130,19 +131,19 @@ macro_rules! impl_vec_simple_array { }) } - fn as_slice_then R>(&self, f: F) -> R { - f(&self.to_vec()) + fn using_encoded R>(&self, f: F) -> R { + f(&self.encode()) } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { use rstd::iter::Extend; let len = self.len(); assert!(len <= u32::max_value() as usize, "Attempted to serialize vec with too many elements."); - let mut r: Vec = Vec::new().join(&(len as u32)); + let mut r: Vec = Vec::new().and(&(len as u32)); for item in self { - r.extend(item.to_vec()); + r.extend(item.encode()); } r } @@ -170,19 +171,15 @@ impl Slicable for Vec { }) } - fn as_slice_then R>(&self, f: F) -> R { - f(&self.to_vec()) - } - - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { use rstd::iter::Extend; let len = self.len(); assert!(len <= u32::max_value() as usize, "Attempted to serialize vec with too many elements."); - let mut r: Vec = Vec::new().join(&(len as u32)); + let mut r: Vec = Vec::new().and(&(len as u32)); for item in self { - r.extend(item.to_vec()); + r.extend(item.encode()); } r } @@ -193,11 +190,11 @@ impl Slicable for () { Some(()) } - fn as_slice_then R>(&self, f: F) -> R { + fn using_encoded R>(&self, f: F) -> R { f(&[]) } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { Vec::new() } } @@ -212,8 +209,8 @@ macro_rules! tuple_impl { } } - fn as_slice_then R>(&self, f: F) -> R { - self.0.as_slice_then(f) + fn using_encoded R>(&self, f: F) -> R { + self.0.using_encoded(f) } } }; @@ -234,7 +231,7 @@ macro_rules! tuple_impl { )) } - fn as_slice_then(&self, f: PROCESS) -> RETURN + fn using_encoded(&self, f: PROCESS) -> RETURN where PROCESS: FnOnce(&[u8]) -> RETURN { let mut v = Vec::new(); @@ -244,8 +241,8 @@ macro_rules! tuple_impl { $(ref $rest),+ ) = *self; - $first.as_slice_then(|s| v.extend(s)); - $($rest.as_slice_then(|s| v.extend(s));)+ + $first.using_encoded(|s| v.extend(s)); + $($rest.using_encoded(|s| v.extend(s));)+ f(v.as_slice()) } @@ -271,7 +268,7 @@ mod tests { #[test] fn vec_is_slicable() { let v = b"Hello world".to_vec(); - v.as_slice_then(|ref slice| + v.using_encoded(|ref slice| assert_eq!(slice, &b"\x0b\0\0\0Hello world") ); } diff --git a/substrate/executor/src/wasm_executor.rs b/substrate/executor/src/wasm_executor.rs index 60f437081a818..fcc1b2b5646c1 100644 --- a/substrate/executor/src/wasm_executor.rs +++ b/substrate/executor/src/wasm_executor.rs @@ -378,11 +378,11 @@ mod tests { let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); assert_eq!( WasmExecutor.call(&mut ext, &test_code[..], "test_blake2_256", &[]).unwrap(), - blake2_256(&b""[..]).to_vec() + blake2_256(&b""[..]).encode() ); assert_eq!( WasmExecutor.call(&mut ext, &test_code[..], "test_blake2_256", b"Hello world!").unwrap(), - blake2_256(&b"Hello world!"[..]).to_vec() + blake2_256(&b"Hello world!"[..]).encode() ); } @@ -435,7 +435,9 @@ mod tests { let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); assert_eq!( WasmExecutor.call(&mut ext, &test_code[..], "test_enumerated_trie_root", &[]).unwrap(), - ordered_trie_root(vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()]).0.to_vec() + ordered_trie_root(vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()]).0.encode() ); } + + } diff --git a/substrate/executor/wasm/src/lib.rs b/substrate/executor/wasm/src/lib.rs index 2002d3cefc94d..48bbd04dca966 100644 --- a/substrate/executor/wasm/src/lib.rs +++ b/substrate/executor/wasm/src/lib.rs @@ -14,26 +14,26 @@ use runtime_io::{ }; fn test_blake2_256(input: &[u8]) -> Vec { - blake2_256(&input).to_vec() + blake2_256(&input).encode() } fn test_twox_256(input: &[u8]) -> Vec { - twox_256(&input).to_vec() + twox_256(&input).encode() } fn test_twox_128(input: &[u8]) -> Vec { - twox_128(&input).to_vec() + twox_128(&input).encode() } fn test_ed25519_verify(input: &[u8]) -> Vec { let sig = &input[0..64]; let pubkey = &input[64..96]; let msg = b"all ok!"; - [ed25519_verify(sig, &msg[..], pubkey) as u8].to_vec() + [ed25519_verify(sig, &msg[..], pubkey) as u8].encode() } fn test_enumerated_trie_root(_input: &[u8]) -> Vec { - enumerated_trie_root(&[&b"zero"[..], &b"one"[..], &b"two"[..]]).to_vec() + enumerated_trie_root(&[&b"zero"[..], &b"one"[..], &b"two"[..]]).encode() } fn test_data_in(input: &[u8]) -> Vec { @@ -62,7 +62,7 @@ fn test_conditional_panic(input: &[u8]) -> Vec { if input.len() > 0 { panic!("test panic"); } - input.to_vec() + input.encode() } impl_stubs!(test_data_in, test_empty_return, test_panic, test_conditional_panic, diff --git a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index 2b8e909b3e4b2e6608e409e5a5b1cf6d86e1fa33..1bca666aa1c9f94e13be0ecefc8ea82c7875ef4a 100644 GIT binary patch delta 148 zcmZ3UyF7QpY8J)`lh?4c0!bs*e#Qx#53y=70jam_tHn7sNDD|Xa63+zyg*(RsNk6V zV<5Ro!3RiAP})3smEu#N$_Yx-8G)3BN*oL0ht2I8S9r}PNOMbU;ALPCWME*p0HlS1 q^eH9=22LQ&;J87WTQE7XATc?!q*5WjEVU>tC%>G*@xtVZW?}#g`Y;jz delta 148 zcmZ3UyF7QpY8J)^lh?4c0!bs*e#Qrz53y=70jam_tHn7MNDD|Xa67h4ULdauRB%lG zF_2uP-~%KlC~cm+O7SUB*HUghbGKx(N<91G)z%`BQ%c+DnAb4zUCWnd6wU|_faq=kX> pDJBL6P9V+TxIvm*FgdXxF*&oOQX#)AwJ0qoznsDG!el;kF#s;!D)s;X delta 148 zcmZ3Iwk50KRKVdCS diff --git a/substrate/network/src/lib.rs b/substrate/network/src/lib.rs index 2897dbcba8054..d7053272cebad 100644 --- a/substrate/network/src/lib.rs +++ b/substrate/network/src/lib.rs @@ -59,5 +59,5 @@ pub use network::{NonReservedPeerMode, ConnectionFilter, ConnectionDirection, Ne // TODO: move it elsewhere fn header_hash(header: &primitives::Header) -> primitives::block::HeaderHash { - primitives::hashing::blake2_256(&ser::to_vec(header)).into() + primitives::hashing::blake2_256(&ser::encode(header)).into() } diff --git a/substrate/primitives/src/block.rs b/substrate/primitives/src/block.rs index 41957f577464a..ba34dd085f08a 100644 --- a/substrate/primitives/src/block.rs +++ b/substrate/primitives/src/block.rs @@ -41,8 +41,8 @@ impl Slicable for Transaction { Vec::::decode(input).map(Transaction) } - fn as_slice_then R>(&self, f: F) -> R { - self.0.as_slice_then(f) + fn using_encoded R>(&self, f: F) -> R { + self.0.using_encoded(f) } } @@ -58,8 +58,8 @@ impl Slicable for Log { Vec::::decode(input).map(Log) } - fn as_slice_then R>(&self, f: F) -> R { - self.0.as_slice_then(f) + fn using_encoded R>(&self, f: F) -> R { + self.0.using_encoded(f) } } @@ -78,8 +78,8 @@ impl Slicable for Digest { Vec::::decode(input).map(|logs| Digest { logs }) } - fn as_slice_then R>(&self, f: F) -> R { - self.logs.as_slice_then(f) + fn using_encoded R>(&self, f: F) -> R { + self.logs.using_encoded(f) } } @@ -104,18 +104,14 @@ impl Slicable for Block { }) } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let mut v = Vec::new(); - v.extend(self.header.to_vec()); - v.extend(self.transactions.to_vec()); + v.extend(self.header.encode()); + v.extend(self.transactions.encode()); v } - - fn as_slice_then R>(&self, f: F) -> R { - f(self.to_vec().as_slice()) - } } /// A relay chain block header. @@ -162,21 +158,17 @@ impl Slicable for Header { }) } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let mut v = Vec::new(); - self.parent_hash.as_slice_then(|s| v.extend(s)); - self.number.as_slice_then(|s| v.extend(s)); - self.state_root.as_slice_then(|s| v.extend(s)); - self.transaction_root.as_slice_then(|s| v.extend(s)); - self.digest.as_slice_then(|s| v.extend(s)); + self.parent_hash.using_encoded(|s| v.extend(s)); + self.number.using_encoded(|s| v.extend(s)); + self.state_root.using_encoded(|s| v.extend(s)); + self.transaction_root.using_encoded(|s| v.extend(s)); + self.digest.using_encoded(|s| v.extend(s)); v } - - fn as_slice_then R>(&self, f: F) -> R { - f(self.to_vec().as_slice()) - } } #[cfg(test)] @@ -207,7 +199,7 @@ mod tests { } }"#); - let v = header.to_vec(); + let v = header.encode(); assert_eq!(Header::decode(&mut &v[..]).unwrap(), header); } } diff --git a/substrate/primitives/src/hash.rs b/substrate/primitives/src/hash.rs index b3c069f4a55d0..5503aa4198e13 100644 --- a/substrate/primitives/src/hash.rs +++ b/substrate/primitives/src/hash.rs @@ -44,8 +44,8 @@ macro_rules! impl_rest { <[u8; $len] as ::codec::Slicable>::decode(input).map($name) } - fn as_slice_then R>(&self, f: F) -> R { - self.0.as_slice_then(f) + fn using_encoded R>(&self, f: F) -> R { + self.0.using_encoded(f) } } } diff --git a/substrate/primitives/src/lib.rs b/substrate/primitives/src/lib.rs index 3822a77d8c649..1c282fe42e92e 100644 --- a/substrate/primitives/src/lib.rs +++ b/substrate/primitives/src/lib.rs @@ -53,6 +53,7 @@ extern crate substrate_serializer; extern crate pretty_assertions; // TODO: factor out to separate crate. +#[macro_export] macro_rules! try_opt { ($e: expr) => { match $e { @@ -62,6 +63,14 @@ macro_rules! try_opt { } } +#[macro_export] +macro_rules! map { + ($( $name:expr => $value:expr ),*) => ( + vec![ $( ( $name, $value ) ),* ].into_iter().collect() + ) +} + + #[cfg(feature = "std")] pub mod bytes; #[cfg(feature = "std")] diff --git a/substrate/runtime-io/with_std.rs b/substrate/runtime-io/with_std.rs index bcedb481162b5..0eadb7a27cf1b 100644 --- a/substrate/runtime-io/with_std.rs +++ b/substrate/runtime-io/with_std.rs @@ -138,7 +138,7 @@ macro_rules! impl_stubs { }; let output = $invoke(input); - Some($crate::codec::Slicable::to_vec(&output)) + Some($crate::codec::Slicable::encode(&output)) } )* _ => None, diff --git a/substrate/runtime-io/without_std.rs b/substrate/runtime-io/without_std.rs index a4d8e4076d5ee..1d4e286b402b6 100644 --- a/substrate/runtime-io/without_std.rs +++ b/substrate/runtime-io/without_std.rs @@ -199,7 +199,7 @@ macro_rules! impl_stubs { }; let output = ($invoke)(input); - let output = $crate::codec::Slicable::to_vec(&output); + let output = $crate::codec::Slicable::encode(&output); let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); // Leak the output vector to avoid it being freed. diff --git a/substrate/runtime-support/Cargo.toml b/substrate/runtime-support/Cargo.toml new file mode 100644 index 0000000000000..2acbd53df9af7 --- /dev/null +++ b/substrate/runtime-support/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "substrate-runtime-support" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +hex-literal = "0.1.0" +substrate-runtime-std = { path = "../runtime-std", default_features = false } +substrate-runtime-io = { path = "../runtime-io", default_features = false } +environmental = { path = "../environmental", optional = true } +substrate-state-machine = { path = "../state-machine", optional = true } +substrate-primitives = { path = "../primitives", default_features = false } +substrate-codec = { path = "../codec", default_features = false } + +[features] +default = ["std"] +std = [ + "environmental", + "substrate-state-machine", + "substrate-primitives/std", + "substrate-runtime-io/std", + "substrate-codec/std", + "substrate-runtime-std/std", +] +nightly = [] +strict = [] diff --git a/polkadot/runtime/src/support/hashable.rs b/substrate/runtime-support/src/hashable.rs similarity index 92% rename from polkadot/runtime/src/support/hashable.rs rename to substrate/runtime-support/src/hashable.rs index b6ad77539653f..79a5c352b3b54 100644 --- a/polkadot/runtime/src/support/hashable.rs +++ b/substrate/runtime-support/src/hashable.rs @@ -27,12 +27,12 @@ pub trait Hashable: Sized { impl Hashable for T { fn blake2_256(&self) -> [u8; 32] { - blake2_256(&self.to_vec()) + blake2_256(&self.encode()) } fn twox_128(&self) -> [u8; 16] { - twox_128(&self.to_vec()) + twox_128(&self.encode()) } fn twox_256(&self) -> [u8; 32] { - twox_256(&self.to_vec()) + twox_256(&self.encode()) } } diff --git a/polkadot/runtime/src/support/mod.rs b/substrate/runtime-support/src/lib.rs similarity index 73% rename from polkadot/runtime/src/support/mod.rs rename to substrate/runtime-support/src/lib.rs index 652fb82aa67d5..742fcfa2371f6 100644 --- a/polkadot/runtime/src/support/mod.rs +++ b/substrate/runtime-support/src/lib.rs @@ -16,21 +16,24 @@ //! Support code for the runtime. -mod environment; +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate substrate_runtime_std as rstd; +extern crate substrate_runtime_io as runtime_io; +extern crate substrate_codec as codec; +extern crate substrate_primitives as primitives; +#[macro_use] +#[cfg(any(feature = "std", test))] +extern crate hex_literal; + pub mod storage; mod hashable; -#[cfg(feature = "std")] -mod statichex; #[macro_use] #[cfg(feature = "std")] mod testing; -pub use self::environment::with_env; pub use self::storage::StorageVec; pub use self::hashable::Hashable; #[cfg(feature = "std")] -pub use self::statichex::{StaticHexConversion, StaticHexInto}; - -#[cfg(feature = "std")] -pub use self::testing::{AsBytesRef, HexDisplay, one, two}; +pub use self::testing::{one, two}; diff --git a/polkadot/runtime/src/support/storage.rs b/substrate/runtime-support/src/storage.rs similarity index 89% rename from polkadot/runtime/src/support/storage.rs rename to substrate/runtime-support/src/storage.rs index 8306906914b87..9896cb07c61ed 100644 --- a/polkadot/runtime/src/support/storage.rs +++ b/substrate/runtime-support/src/storage.rs @@ -18,33 +18,14 @@ use rstd::prelude::*; use runtime_io::{self, twox_128}; -use codec::{Input, Slicable, KeyedVec}; +use codec::{Slicable, KeyedVec}; // TODO: consider using blake256 to avoid possible preimage attack. -struct IncrementalInput<'a> { - key: &'a [u8], - pos: usize, -} - -impl<'a> Input for IncrementalInput<'a> { - fn read(&mut self, into: &mut [u8]) -> usize { - let len = runtime_io::read_storage(self.key, into, self.pos); - let read = ::rstd::cmp::min(len, into.len()); - self.pos += read; - read - } -} - /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. pub fn get(key: &[u8]) -> Option { - let key = twox_128(key); - let mut input = IncrementalInput { - key: &key[..], - pos: 0, - }; - - Slicable::decode(&mut input) + let raw = runtime_io::storage(&twox_128(key)[..]); + Slicable::decode(&mut &raw[..]) } /// Return the value of the item in storage under `key`, or the type's default if there is no @@ -67,12 +48,12 @@ pub fn get_or_else T>(key: &[u8], default_va /// Please `value` in storage under `key`. pub fn put(key: &[u8], value: &T) { - value.as_slice_then(|slice| runtime_io::set_storage(&twox_128(key)[..], slice)); + value.using_encoded(|slice| runtime_io::set_storage(&twox_128(key)[..], slice)); } /// Please `value` in storage under `key`. pub fn place(key: &[u8], value: T) { - value.as_slice_then(|slice| runtime_io::set_storage(&twox_128(key)[..], slice)); + value.using_encoded(|slice| runtime_io::set_storage(&twox_128(key)[..], slice)); } /// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. @@ -161,16 +142,12 @@ pub trait StorageVec { } pub mod unhashed { - use super::{runtime_io, Slicable, KeyedVec, Vec, IncrementalInput}; + use super::{runtime_io, Slicable, KeyedVec, Vec}; /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. pub fn get(key: &[u8]) -> Option { - let mut input = IncrementalInput { - key, - pos: 0, - }; - - T::decode(&mut input) + let raw = runtime_io::storage(key); + T::decode(&mut &raw[..]) } /// Return the value of the item in storage under `key`, or the type's default if there is no @@ -193,12 +170,12 @@ pub mod unhashed { /// Please `value` in storage under `key`. pub fn put(key: &[u8], value: &T) { - value.as_slice_then(|slice| runtime_io::set_storage(key, slice)); + value.using_encoded(|slice| runtime_io::set_storage(key, slice)); } /// Please `value` in storage under `key`. pub fn place(key: &[u8], value: T) { - value.as_slice_then(|slice| runtime_io::set_storage(key, slice)); + value.using_encoded(|slice| runtime_io::set_storage(key, slice)); } /// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. @@ -291,7 +268,7 @@ pub mod unhashed { mod tests { use super::*; use std::collections::HashMap; - use support::HexDisplay; + use primitives::hexdisplay::HexDisplay; use runtime_io::{storage, twox_128, TestExternalities, with_externalities}; #[test] @@ -358,16 +335,4 @@ mod tests { assert_eq!(x, y); }); } - - #[test] - fn proposals_can_be_stored() { - use polkadot_primitives::Proposal; - let mut t = TestExternalities { storage: HashMap::new(), }; - with_externalities(&mut t, || { - let x = Proposal::StakingSetSessionsPerEra(25519); - put(b":test", &x); - let y: Proposal = get(b":test").unwrap(); - assert_eq!(x, y); - }); - } } diff --git a/substrate/runtime-support/src/testing.rs b/substrate/runtime-support/src/testing.rs new file mode 100644 index 0000000000000..768c56a1e95f3 --- /dev/null +++ b/substrate/runtime-support/src/testing.rs @@ -0,0 +1,28 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Testing helpers. + +use primitives::AuthorityId; + +/// One account (to which we know the secret key). +pub fn one() -> AuthorityId { + hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee") +} +/// Another account (secret key known). +pub fn two() -> AuthorityId { + hex!("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a") +} diff --git a/substrate/serializer/src/lib.rs b/substrate/serializer/src/lib.rs index 9bdda4d019f29..74cf155ce77e8 100644 --- a/substrate/serializer/src/lib.rs +++ b/substrate/serializer/src/lib.rs @@ -34,7 +34,7 @@ pub fn to_string_pretty(value: &T) -> String { } /// Serialize the given data structure as a JSON byte vector. -pub fn to_vec(value: &T) -> Vec { +pub fn encode(value: &T) -> Vec { serde_json::to_vec(value).expect(PROOF) } diff --git a/substrate/test-runtime/Cargo.toml b/substrate/test-runtime/Cargo.toml new file mode 100644 index 0000000000000..481f32f8115ed --- /dev/null +++ b/substrate/test-runtime/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "substrate-test-runtime" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +hex-literal = "0.1.0" +log = { version = "0.3", optional = true } +substrate-codec = { path = "../../substrate/codec" } +substrate-runtime-std = { path = "../../substrate/runtime-std" } +substrate-runtime-io = { path = "../../substrate/runtime-io" } +substrate-runtime-support = { path = "../../substrate/runtime-support" } +substrate-primitives = { path = "../../substrate/primitives" } + +[features] +default = ["std"] +std = [ + "substrate-codec/std", + "substrate-runtime-std/std", + "substrate-runtime-io/std", + "substrate-runtime-support/std", + "substrate-primitives/std", + "log" +] diff --git a/substrate/test-runtime/src/block.rs b/substrate/test-runtime/src/block.rs new file mode 100644 index 0000000000000..f85bbd882ec46 --- /dev/null +++ b/substrate/test-runtime/src/block.rs @@ -0,0 +1,48 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! A toy unchecked transaction complete with signature. + +use rstd::prelude::*; +use codec::{Input, Slicable, Joiner}; +use super::{Header, UncheckedTransaction}; + +#[derive(PartialEq, Eq, Clone)] +#[cfg_attr(feature = "std", derive(Debug))] +/// A coupling between a header and a list of transactions. +pub struct Block { + /// The block header. + pub header: Header, + /// The list of transactions in the block. + pub transactions: Vec, +} + +impl Slicable for Block { + fn decode(input: &mut I) -> Option { + Some(Block { + header: Slicable::decode(input)?, + transactions: Slicable::decode(input)?, + }) + } + + fn encode(&self) -> Vec { + Vec::new() + .and(&self.header) + .and(&self.transactions) + } +} + +impl ::codec::NonTrivialSlicable for Block {} diff --git a/substrate/test-runtime/src/genesismap.rs b/substrate/test-runtime/src/genesismap.rs new file mode 100644 index 0000000000000..0dc01c0abce03 --- /dev/null +++ b/substrate/test-runtime/src/genesismap.rs @@ -0,0 +1,68 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Tool for creating the genesis block. + +use std::collections::HashMap; +use runtime_io::twox_128; +use runtime_support::Hashable; +use codec::{KeyedVec, Joiner}; +use primitives::AuthorityId; +use primitives::block::Block; + +/// Configuration of a general Substrate test genesis block. +pub struct GenesisConfig { + pub authorities: Vec, + pub balances: Vec<(AuthorityId, u64)>, +} + +impl GenesisConfig { + pub fn new_simple(authorities: Vec, balance: u64) -> Self { + GenesisConfig { + authorities: authorities.clone(), + balances: authorities.into_iter().map(|a| (a, balance)).collect(), + } + } + + pub fn genesis_map(&self) -> HashMap, Vec> { + let wasm_runtime = include_bytes!("../wasm/genesis.wasm").to_vec(); + self.balances.iter() + .map(|&(account, balance)| (account.to_keyed_vec(b"balance:"), vec![].and(&balance))) + .map(|(k, v)| (twox_128(&k[..])[..].to_vec(), v.to_vec())) + .chain(vec![ + (b":code"[..].into(), wasm_runtime), + (b":auth:len"[..].into(), vec![].and(&(self.authorities.len() as u32))), + ].into_iter()) + .chain(self.authorities.iter() + .enumerate() + .map(|(i, account)| ((i as u32).to_keyed_vec(b":auth:"), vec![].and(account))) + ) + .collect() + } +} + +macro_rules! map { + ($( $name:expr => $value:expr ),*) => ( + vec![ $( ( $name, $value ) ),* ].into_iter().collect() + ) +} + +pub fn additional_storage_with_genesis(genesis_block: &Block) -> HashMap, Vec> { + use codec::Slicable; + map![ + twox_128(&b"latest"[..]).encode() => genesis_block.header.blake2_256().encode() + ] +} diff --git a/substrate/test-runtime/src/lib.rs b/substrate/test-runtime/src/lib.rs new file mode 100644 index 0000000000000..b5be15fc2317a --- /dev/null +++ b/substrate/test-runtime/src/lib.rs @@ -0,0 +1,74 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! The Substrate runtime. This can be compiled with #[no_std], ready for Wasm. + +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate substrate_runtime_std as rstd; +#[macro_use] +extern crate substrate_runtime_io as runtime_io; +extern crate substrate_runtime_support as runtime_support; +extern crate substrate_codec as codec; +#[cfg_attr(test, macro_use)] extern crate hex_literal; +#[cfg_attr(test, macro_use)] extern crate substrate_primitives as primitives; + +#[cfg(feature = "std")] +pub mod genesismap; +pub mod system; +mod transaction; +mod unchecked_transaction; +mod block; + +use rstd::prelude::*; +use codec::Slicable; + +use primitives::AuthorityId; +use primitives::hash::H512; +pub use primitives::hash::H256; +pub use primitives::block::{Header, Number as BlockNumber, Digest}; +pub use transaction::Transaction; +pub use unchecked_transaction::UncheckedTransaction; +pub use block::Block; + +/// An identifier for an account on this system. +pub type AccountId = AuthorityId; +/// Signature for our transactions. +pub type Signature = H512; +/// A simple hash type for all our hashing. +pub type Hash = H256; + +/// Run whatever tests we have. +pub fn run_tests(mut input: &[u8]) -> Vec { + use runtime_io::print; + + print("run_tests..."); + let block = Block::decode(&mut input).unwrap(); + print("deserialised block."); + let stxs = block.transactions.iter().map(Slicable::encode).collect::>(); + print("reserialised transactions."); + [stxs.len() as u8].encode() +} + +pub mod apis { + use system; + + impl_stubs!( + execute_block => |block| system::execute_block(block), + execute_transaction => |(header, utx)| system::execute_transaction(utx, header), + finalise_block => |header| system::finalise_block(header) + ); +} diff --git a/substrate/test-runtime/src/system.rs b/substrate/test-runtime/src/system.rs new file mode 100644 index 0000000000000..d6a9426538d48 --- /dev/null +++ b/substrate/test-runtime/src/system.rs @@ -0,0 +1,178 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! System manager: Handles all of the top-level stuff; executing block/transaction, setting code +//! and depositing logs. + +use rstd::prelude::*; +use runtime_io::{storage_root, enumerated_trie_root, ed25519_verify}; +use runtime_support::{Hashable, storage}; +use codec::{KeyedVec, Slicable}; +use super::{AccountId, UncheckedTransaction, H256 as Hash, Block, Header}; + +const NONCE_OF: &[u8] = b"nonce:"; +const BALANCE_OF: &[u8] = b"balance:"; +const LATEST_BLOCK_HASH: &[u8] = b"latest"; + +pub fn latest_block_hash() -> Hash { + storage::get(LATEST_BLOCK_HASH).expect("There must always be a latest block") +} + +pub fn balance_of(who: AccountId) -> u64 { + storage::get_or(&who.to_keyed_vec(BALANCE_OF), 0) +} + +pub fn nonce_of(who: AccountId) -> u64 { + storage::get_or(&who.to_keyed_vec(NONCE_OF), 0) +} + +/// Actually execute all transitioning for `block`. +pub fn execute_block(block: Block) { + let ref header = block.header; + + // check parent_hash is correct. + assert!( + header.number > 0 && latest_block_hash() == header.parent_hash, + "Parent hash should be valid." + ); + + // check transaction trie root represents the transactions. + let txs = block.transactions.iter().map(Slicable::encode).collect::>(); + let txs = txs.iter().map(Vec::as_slice).collect::>(); + let txs_root = enumerated_trie_root(&txs).into(); + info_expect_equal_hash(&header.transaction_root, &txs_root); + assert!(header.transaction_root == txs_root, "Transaction trie root must be valid."); + + // execute transactions + block.transactions.iter().for_each(execute_transaction_backend); + + // check storage root. + let storage_root = storage_root().into(); + info_expect_equal_hash(&header.state_root, &storage_root); + assert!(header.state_root == storage_root, "Storage root must match that calculated."); + + // put the header hash into storage. + storage::put(LATEST_BLOCK_HASH, &header.blake2_256()); +} + +/// Execute a transaction outside of the block execution function. +/// This doesn't attempt to validate anything regarding the block. +pub fn execute_transaction(utx: UncheckedTransaction, header: Header) -> Header { + execute_transaction_backend(&utx); + header +} + +/// Finalise the block - it is up the caller to ensure that all header fields are valid +/// except state-root. +pub fn finalise_block(mut header: Header) -> Header { + header.state_root = storage_root().into(); + header +} + +fn execute_transaction_backend(utx: &UncheckedTransaction) { + // check signature + let ref tx = utx.tx; + let msg = ::codec::Slicable::encode(tx); + assert!(ed25519_verify(&utx.signature.0, &msg, &tx.from), + "All transactions should be properly signed"); + + // check nonce + let nonce_key = tx.from.to_keyed_vec(NONCE_OF); + let expected_nonce: u64 = storage::get_or(&nonce_key, 0); + assert!(tx.nonce == expected_nonce, "All transactions should have the correct nonce"); + + // increment nonce in storage + storage::put(&nonce_key, &(expected_nonce + 1)); + + // check sender balance + let from_balance_key = tx.from.to_keyed_vec(BALANCE_OF); + let from_balance: u64 = storage::get_or(&from_balance_key, 0); + assert!(tx.amount <= from_balance, "All transactions should transfer at most the sender balance"); + + // enact transfer + let to_balance_key = tx.to.to_keyed_vec(BALANCE_OF); + let to_balance: u64 = storage::get_or(&to_balance_key, 0); + storage::put(&from_balance_key, &(from_balance - tx.amount)); + storage::put(&to_balance_key, &(to_balance + tx.amount)); +} + +#[cfg(feature = "std")] +fn info_expect_equal_hash(given: &Hash, expected: &Hash) { + use primitives::hexdisplay::HexDisplay; + if given != expected { + println!("Hash: given={}, expected={}", HexDisplay::from(&given.0), HexDisplay::from(&expected.0)); + } +} + +#[cfg(not(feature = "std"))] +fn info_expect_equal_hash(given: &Hash, expected: &Hash) { + if given != expected { + ::runtime_io::print("Hash not equal"); + ::runtime_io::print(&given.0[..]); + ::runtime_io::print(&expected.0[..]); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use runtime_io::{with_externalities, twox_128, TestExternalities}; + use codec::{Joiner, KeyedVec, Slicable}; + use runtime_support::{one, two}; + use primitives::hexdisplay::HexDisplay; + use ::{Header, Digest, UncheckedTransaction, Transaction}; + + fn new_test_ext() -> TestExternalities { + let one = one(); + let two = two(); + let three = [3u8; 32]; + + TestExternalities { storage: map![ + twox_128(b"latest").to_vec() => vec![69u8; 32], + twox_128(b":auth:len").to_vec() => vec![].and(&3u32), + twox_128(&0u32.to_keyed_vec(b":auth:")).to_vec() => one.to_vec(), + twox_128(&1u32.to_keyed_vec(b":auth:")).to_vec() => two.to_vec(), + twox_128(&2u32.to_keyed_vec(b":auth:")).to_vec() => three.to_vec(), + twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + ], } + } + + #[test] + fn block_import_works() { + let one = one(); + let two = two(); + + let mut t = new_test_ext(); + + let h = Header { + parent_hash: [69u8; 32].into(), + number: 1, + state_root: hex!("89b5f5775a45310806a77f421d66bffeff190a519c55f2dcb21f251c2b714524").into(), + transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(), + digest: Digest { logs: vec![], }, + }; + + let b = Block { + header: h, + transactions: vec![], + }; + + with_externalities(&mut t, || { + execute_block(b); + }); + } +} diff --git a/substrate/test-runtime/src/transaction.rs b/substrate/test-runtime/src/transaction.rs new file mode 100644 index 0000000000000..858ac4efa0fb4 --- /dev/null +++ b/substrate/test-runtime/src/transaction.rs @@ -0,0 +1,56 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! A toy transaction. + +use rstd::prelude::*; +use codec::{Input, Slicable, Joiner}; +use super::AccountId; + +/// An instruction to do something. +#[derive(PartialEq, Eq, Clone)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct Transaction { + /// Who is sending. + pub from: AccountId, + /// Who to send to. + pub to: AccountId, + /// How much to send. + pub amount: u64, + /// How many transactions `self.from` already sent. + pub nonce: u64, +} + +impl Slicable for Transaction { + fn decode(input: &mut I) -> Option { + Some(Transaction { + from: Slicable::decode(input)?, + to: Slicable::decode(input)?, + amount: Slicable::decode(input)?, + nonce: Slicable::decode(input)?, + }) + } + + fn encode(&self) -> Vec { + Vec::new() + .and(&self.from) + .and(&self.to) + .and(&self.amount) + .and(&self.nonce) + } +} + +impl ::codec::NonTrivialSlicable for Transaction {} diff --git a/substrate/test-runtime/src/unchecked_transaction.rs b/substrate/test-runtime/src/unchecked_transaction.rs new file mode 100644 index 0000000000000..6ea3af310fc19 --- /dev/null +++ b/substrate/test-runtime/src/unchecked_transaction.rs @@ -0,0 +1,63 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! A toy unchecked transaction complete with signature. + +use rstd::prelude::*; +use codec::{Input, Slicable}; +use super::{Signature, Transaction}; + +/// A transactions right from the external world. Unchecked. +#[derive(PartialEq, Eq, Clone)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct UncheckedTransaction { + /// The actual transaction information. + pub tx: Transaction, + /// The signature; should be an Ed25519 signature applied to the serialised `transaction` field. + pub signature: Signature, +} + +impl Slicable for UncheckedTransaction { + fn decode(input: &mut I) -> Option { + // This is a little more complicated than usua since the binary format must be compatible + // with substrate's generic `Vec` type. Basically this just means accepting that there + // will be a prefix of u32, which has the total number of bytes following (we don't need + // to use this). + let _length_do_not_remove_me_see_above: u32 = Slicable::decode(input)?; + Some(UncheckedTransaction { + tx: Slicable::decode(input)?, + signature: Slicable::decode(input)?, + }) + } + + fn encode(&self) -> Vec { + let mut v = Vec::new(); + + // need to prefix with the total length as u32 to ensure it's binary comptible with + // Vec. we'll make room for it here, then overwrite once we know the length. + v.extend(&[0u8; 4]); + + self.tx.using_encoded(|s| v.extend(s)); + self.signature.using_encoded(|s| v.extend(s)); + + let length = (v.len() - 4) as u32; + length.using_encoded(|s| v[0..4].copy_from_slice(s)); + + v + } +} + +impl ::codec::NonTrivialSlicable for UncheckedTransaction {} diff --git a/substrate/test-runtime/wasm/Cargo.lock b/substrate/test-runtime/wasm/Cargo.lock new file mode 100644 index 0000000000000..29ef026e0d771 --- /dev/null +++ b/substrate/test-runtime/wasm/Cargo.lock @@ -0,0 +1,881 @@ +[[package]] +name = "aho-corasick" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ansi_term" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "arrayvec" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "odds 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "arrayvec" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bigint" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bitflags" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "byteorder" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cc" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "coco" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "crunchy" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "ed25519" +version = "0.1.0" +dependencies = [ + "ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-primitives 0.1.0", + "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "either" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "elastic-array" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "env_logger" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "environmental" +version = "0.1.0" + +[[package]] +name = "ethcore-bigint" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "plain_hasher 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ethcore-bytes" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "ethcore-logger" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "isatty 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fixed-hash" +version = "0.1.3" +source = "git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm#8dc457899afdaf968ff7f16140b03d1e37b01d71" +dependencies = [ + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "gcc" +version = "0.3.54" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "hashdb" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "heapsize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hex-literal" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hex-literal-impl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hex-literal-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "isatty" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "keccak-hash" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lazy_static" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazy_static" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "log" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "log" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memchr" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memorydb" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nodrop" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "num_cpus" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "odds" +version = "0.2.26" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "owning_ref" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot_core" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "patricia-trie" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-logger 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "plain_hasher" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro-hack" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-hack-impl 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro-hack-impl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "pwasm-alloc" +version = "0.1.0" +dependencies = [ + "pwasm-libc 0.1.0", + "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pwasm-libc" +version = "0.1.0" + +[[package]] +name = "quote" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon-core" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "redox_syscall" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "redox_termios" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "ring" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rlp" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc-hex" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc-hex" +version = "2.0.0" +source = "git+https://github.com/rphmeier/rustc-hex.git#ee2ec40b9062ac7769ccb9dc891d6dc2cc9009d7" + +[[package]] +name = "rustc_version" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "scopeguard" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "semver" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde_derive" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_derive_internals" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "smallvec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "stable_deref_trait" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "substrate-codec" +version = "0.1.0" +dependencies = [ + "substrate-runtime-std 0.1.0", +] + +[[package]] +name = "substrate-primitives" +version = "0.1.0" +dependencies = [ + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "fixed-hash 0.1.3 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)", + "rustc-hex 2.0.0 (git+https://github.com/rphmeier/rustc-hex.git)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-codec 0.1.0", + "substrate-runtime-std 0.1.0", + "twox-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.1.2 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)", +] + +[[package]] +name = "substrate-runtime-io" +version = "0.1.0" +dependencies = [ + "ed25519 0.1.0", + "environmental 0.1.0", + "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-codec 0.1.0", + "substrate-primitives 0.1.0", + "substrate-runtime-std 0.1.0", + "substrate-state-machine 0.1.0", + "triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-runtime-std" +version = "0.1.0" +dependencies = [ + "pwasm-alloc 0.1.0", + "pwasm-libc 0.1.0", + "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-runtime-support" +version = "0.1.0" +dependencies = [ + "environmental 0.1.0", + "hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-codec 0.1.0", + "substrate-primitives 0.1.0", + "substrate-runtime-io 0.1.0", + "substrate-runtime-std 0.1.0", + "substrate-state-machine 0.1.0", +] + +[[package]] +name = "substrate-state-machine" +version = "0.1.0" +dependencies = [ + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "patricia-trie 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-primitives 0.1.0", + "triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-test-runtime" +version = "0.1.0" +dependencies = [ + "substrate-codec 0.1.0", + "substrate-primitives 0.1.0", + "substrate-runtime-io 0.1.0", + "substrate-runtime-std 0.1.0", + "substrate-runtime-support 0.1.0", +] + +[[package]] +name = "syn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "synom" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "termion" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread_local" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "time" +version = "0.1.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tiny-keccak" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "triehash" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "twox-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "uint" +version = "0.1.2" +source = "git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm#8dc457899afdaf968ff7f16140b03d1e37b01d71" +dependencies = [ + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-xid" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "untrusted" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "utf8-ranges" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" +"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" +"checksum arrayvec 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)" = "06f59fe10306bb78facd90d28c2038ad23ffaaefa85bac43c8a434cde383334f" +"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" +"checksum bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5442186ef6560f30f1ee4b9c1e4c87a35a6879d3644550cc248ec2b955eb5fcd" +"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" +"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" +"checksum cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "deaf9ec656256bb25b404c51ef50097207b9cbb29c933d31f92cae5a8a0ffee0" +"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" +"checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd" +"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" +"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" +"checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" +"checksum elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "258ff6a9a94f648d0379dbd79110e057edbb53eb85cc237e33eadf8e5a30df85" +"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" +"checksum ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcb5af77e74a8f70e9c3337e069c37bc82178ef1b459c02091f73c4ad5281eb5" +"checksum ethcore-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3977c772cd6c5c22e1c7cfa208e4c3b746bd6c3a6c8eeec0999a6b2103015ad5" +"checksum ethcore-logger 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fd5813e49546030be7d134e775088d56b8ff4ab60617b90e93d4f0513da4c5b" +"checksum fixed-hash 0.1.3 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)" = "" +"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" +"checksum hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d97be07c358c5b461268b4ce60304024c5fa5acfd4bd8cd743639f0252003cf5" +"checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" +"checksum hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd546ef520ab3745f1aae5f2cdc6de9e6498e94d1ab138b9eb3ddfbf335847fb" +"checksum hex-literal-impl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2ea76da4c7f1a54d01d54985566d3fdd960b2bbd7b970da024821c883c2d9631" +"checksum isatty 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f2a233726c7bb76995cec749d59582e5664823b7245d4970354408f1d79a7a2" +"checksum keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f300c1f149cd9ca5214eed24f6e713a597517420fb8b15499824aa916259ec1" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" +"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" +"checksum libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "1e5d97d6708edaa407429faa671b942dc0f2727222fb6b6539bf1db936e4b121" +"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" +"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" +"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" +"checksum memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "013b7e4c5e10c764936ebc6bd3662d8e3c92292d267bf6a42ef3f5cad9c793ee" +"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" +"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" +"checksum odds 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)" = "4eae0151b9dacf24fcc170d9995e511669a082856a91f958a2fe380bfab3fb22" +"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" +"checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e" +"checksum parking_lot_core 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "9f35048d735bb93dd115a0030498785971aab3234d311fbe273d020084d26bd8" +"checksum patricia-trie 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1e2f638d79aba5c4a71a4f373df6e3cd702250a53b7f0ed4da1e2a7be9737ae" +"checksum plain_hasher 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83ae80873992f511142c07d0ec6c44de5636628fdb7e204abd655932ea79d995" +"checksum proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ba8d4f9257b85eb6cdf13f055cea3190520aab1409ca2ab43493ea4820c25f0" +"checksum proc-macro-hack-impl 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5cb6f960ad471404618e9817c0e5d10b1ae74cfdf01fab89ea0641fe7fb2892" +"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" +"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" +"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" +"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8" +"checksum rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e64b609139d83da75902f88fd6c01820046840a18471e4dfcd5ac7c0f46bea53" +"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" +"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "744554e01ccbd98fff8c457c3b092cd67af62a555a43bfe97ae8a0451f7799fa" +"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" +"checksum ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6f7d28b30a72c01b458428e0ae988d4149c20d902346902be881e3edc4bb325c" +"checksum rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "babe6fce20c0ca9b1582998734c4569082d0ad08e43772a1c6c40aef4f106ef9" +"checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e" +"checksum rustc-hex 2.0.0 (git+https://github.com/rphmeier/rustc-hex.git)" = "" +"checksum rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9743a7670d88d5d52950408ecdb7c71d8986251ab604d4689dd2ca25c9bca69" +"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" +"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +"checksum serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "db99f3919e20faa51bb2996057f5031d8685019b5a06139b1ce761da671b8526" +"checksum serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "f4ba7591cfe93755e89eeecdbcc668885624829b020050e6aec99c2a03bd3fd0" +"checksum serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e03f1c9530c3fb0a0a5c9b826bdd9246a5921ae995d75f512ac917fc4dd55b5" +"checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9" +"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" +"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" +"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" +"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" +"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" +"checksum tiny-keccak 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e9241752647ca572f12c9b520a5d360d9099360c527770647e694001646a1d0" +"checksum triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9291c7f0fae44858b5e087dd462afb382354120003778f1695b44aab98c7abd7" +"checksum twox-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "475352206e7a290c5fccc27624a163e8d0d115f7bb60ca18a64fc9ce056d7435" +"checksum uint 0.1.2 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)" = "" +"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" +"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +"checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae" +"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/substrate/test-runtime/wasm/Cargo.toml b/substrate/test-runtime/wasm/Cargo.toml new file mode 100644 index 0000000000000..93886c1f3a5b5 --- /dev/null +++ b/substrate/test-runtime/wasm/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "substrate-test-runtime" +version = "0.1.0" +authors = ["Parity Technologies "] + +[lib] +crate-type = ["cdylib"] + +[dependencies] +substrate-codec = { path = "../../codec", default-features = false } +substrate-runtime-std = { path = "../../runtime-std", default-features = false } +substrate-runtime-io = { path = "../../runtime-io", default-features = false } +substrate-runtime-support = { path = "../../runtime-support", default-features = false } +substrate-primitives = { path = "../../primitives", default-features = false } + +[features] +default = [] +std = [ + "substrate-codec/std", + "substrate-runtime-io/std", + "substrate-runtime-std/std", + "substrate-runtime-support/std", + "substrate-primitives/std" +] + +[profile.release] +panic = "abort" + +[workspace] +members = [] diff --git a/substrate/test-runtime/wasm/build.sh b/substrate/test-runtime/wasm/build.sh new file mode 100755 index 0000000000000..e2d1faeb7312b --- /dev/null +++ b/substrate/test-runtime/wasm/build.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -e + +cargo +nightly build --target=wasm32-unknown-unknown --release +for i in substrate_test_runtime +do + wasm-gc target/wasm32-unknown-unknown/release/$i.wasm target/wasm32-unknown-unknown/release/$i.compact.wasm +done diff --git a/substrate/test-runtime/wasm/genesis.wasm b/substrate/test-runtime/wasm/genesis.wasm new file mode 100644 index 0000000000000000000000000000000000000000..3eca5047352e7efbcf6808672b0454858e410327 GIT binary patch literal 31744 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 CcHcSx literal 0 HcmV?d00001 diff --git a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm new file mode 100644 index 0000000000000000000000000000000000000000..f0415f875a21224beeaaaf2f38a6b3ef0c386d17 GIT binary patch literal 31984 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 Date: Thu, 8 Feb 2018 22:36:24 +0100 Subject: [PATCH 4/6] fix runtime_test --- substrate/executor/src/wasm_executor.rs | 11 +++ substrate/executor/wasm/src/lib.rs | 91 +++++++++++-------------- substrate/runtime-io/with_std.rs | 29 ++++---- substrate/runtime-io/without_std.rs | 89 +++++++++++++++--------- 4 files changed, 124 insertions(+), 96 deletions(-) diff --git a/substrate/executor/src/wasm_executor.rs b/substrate/executor/src/wasm_executor.rs index fcc1b2b5646c1..eef0df976d54e 100644 --- a/substrate/executor/src/wasm_executor.rs +++ b/substrate/executor/src/wasm_executor.rs @@ -423,6 +423,17 @@ mod tests { let mut calldata = vec![]; calldata.extend_from_slice(key.public().as_ref()); calldata.extend_from_slice(sig.as_ref()); + + assert_eq!( + WasmExecutor.call(&mut ext, &test_code[..], "test_ed25519_verify", &calldata).unwrap(), + vec![1] + ); + + let other_sig = key.sign(b"all is not ok!"); + let mut calldata = vec![]; + calldata.extend_from_slice(key.public().as_ref()); + calldata.extend_from_slice(other_sig.as_ref()); + assert_eq!( WasmExecutor.call(&mut ext, &test_code[..], "test_ed25519_verify", &calldata).unwrap(), vec![0] diff --git a/substrate/executor/wasm/src/lib.rs b/substrate/executor/wasm/src/lib.rs index 48bbd04dca966..11401a39d7b45 100644 --- a/substrate/executor/wasm/src/lib.rs +++ b/substrate/executor/wasm/src/lib.rs @@ -13,57 +13,42 @@ use runtime_io::{ twox_128, twox_256, ed25519_verify, enumerated_trie_root }; -fn test_blake2_256(input: &[u8]) -> Vec { - blake2_256(&input).encode() -} - -fn test_twox_256(input: &[u8]) -> Vec { - twox_256(&input).encode() -} - -fn test_twox_128(input: &[u8]) -> Vec { - twox_128(&input).encode() -} - -fn test_ed25519_verify(input: &[u8]) -> Vec { - let sig = &input[0..64]; - let pubkey = &input[64..96]; - let msg = b"all ok!"; - [ed25519_verify(sig, &msg[..], pubkey) as u8].encode() -} - -fn test_enumerated_trie_root(_input: &[u8]) -> Vec { - enumerated_trie_root(&[&b"zero"[..], &b"one"[..], &b"two"[..]]).encode() -} - -fn test_data_in(input: &[u8]) -> Vec { - print("set_storage"); - set_storage(b"input", &input); - - print("storage"); - let foo = storage(b"foo"); - - print("set_storage"); - set_storage(b"baz", &foo); - - print("finished!"); - b"all ok!".to_vec() -} - -fn test_empty_return(_input: &[u8]) -> Vec { - Vec::new() -} - -fn test_panic(_input: &[u8]) -> Vec { - panic!("test panic"); -} - -fn test_conditional_panic(input: &[u8]) -> Vec { - if input.len() > 0 { - panic!("test panic"); +impl_stubs!( + test_data_in NO_DECODE => |input| { + print("set_storage"); + set_storage(b"input", input); + + print("storage"); + let foo = storage(b"foo"); + + print("set_storage"); + set_storage(b"baz", &foo); + + print("finished!"); + b"all ok!".to_vec() + }, + test_empty_return NO_DECODE => |_| Vec::new(), + test_panic NO_DECODE => |_| panic!("test panic"), + test_conditional_panic NO_DECODE => |input: &[u8]| { + if input.len() > 0 { + panic!("test panic") + } + input.to_vec() + }, + test_blake2_256 NO_DECODE => |input| blake2_256(input).to_vec(), + test_twox_256 NO_DECODE => |input| twox_256(input).to_vec(), + test_twox_128 NO_DECODE => |input| twox_128(input).to_vec(), + test_ed25519_verify NO_DECODE => |input: &[u8]| { + let mut pubkey = [0; 32]; + let mut sig = [0; 64]; + + pubkey.copy_from_slice(&input[0..32]); + sig.copy_from_slice(&input[32..96]); + + let msg = b"all ok!"; + [ed25519_verify(&sig, &msg[..], &pubkey) as u8].to_vec() + }, + test_enumerated_trie_root NO_DECODE => |_| { + enumerated_trie_root(&[&b"zero"[..], &b"one"[..], &b"two"[..]]).to_vec() } - input.encode() -} - -impl_stubs!(test_data_in, test_empty_return, test_panic, test_conditional_panic, - test_blake2_256, test_twox_256, test_twox_128, test_ed25519_verify, test_enumerated_trie_root); +); diff --git a/substrate/runtime-io/with_std.rs b/substrate/runtime-io/with_std.rs index 0eadb7a27cf1b..cb01133a6c112 100644 --- a/substrate/runtime-io/with_std.rs +++ b/substrate/runtime-io/with_std.rs @@ -126,25 +126,30 @@ pub fn print(value: T) { #[macro_export] macro_rules! impl_stubs { - ( $( $name:ident => $invoke:expr ),* ) => { + ( $( $new_name:ident $($nodecode:ident)* => $invoke: expr ),*) => { /// Dispatch logic for the native runtime. - pub fn dispatch(method: &str, mut data: &[u8]) -> Option> { + pub fn dispatch(method: &str, data: &[u8]) -> Option> { match method { $( - stringify!($name) => { - let input = match $crate::codec::Slicable::decode(&mut data) { - Some(input) => input, - None => panic!("Bad input data provided to {}", stringify!($name)), - }; - - let output = $invoke(input); - Some($crate::codec::Slicable::encode(&output)) - } + stringify!($new_name) => { impl_stubs!(@METHOD data $new_name $($nodecode)* => $invoke) } )* _ => None, } } - } + }; + (@METHOD $data: ident $new_name: ident NO_DECODE => $invoke:expr) => { + Some($invoke($data)) + }; + (@METHOD $data: ident $new_name: ident => $invoke:expr) => {{ + let mut data = $data; + let input = match $crate::codec::Slicable::decode(&mut data) { + Some(input) => input, + None => panic!("Bad input data provided to {}", stringify!($new_name)), + }; + + let output = $invoke(input); + Some($crate::codec::Slicable::to_vec(&output)) + }} } #[cfg(test)] diff --git a/substrate/runtime-io/without_std.rs b/substrate/runtime-io/without_std.rs index 1d4e286b402b6..ecadddeeabdad 100644 --- a/substrate/runtime-io/without_std.rs +++ b/substrate/runtime-io/without_std.rs @@ -14,9 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -extern crate substrate_runtime_std as rstd; + extern crate substrate_primitives as primitives; +#[doc(hidden)] +pub extern crate substrate_runtime_std as rstd; + #[doc(hidden)] pub extern crate substrate_codec as codec; @@ -141,10 +144,10 @@ pub fn twox_128(data: &[u8]) -> [u8; 16] { } /// Verify a ed25519 signature. -pub fn ed25519_verify(sig: &[u8], msg: &[u8], pubkey: &[u8]) -> bool { - sig.len() == 64 && pubkey.len() == 32 && unsafe { - ext_ed25519_verify(msg.as_ptr(), msg.len() as u32, sig.as_ptr(), pubkey.as_ptr()) - } == 0 +pub fn ed25519_verify(sig: &[u8; 64], msg: &[u8], pubkey: &[u8; 32]) -> bool { + unsafe { + ext_ed25519_verify(msg.as_ptr(), msg.len() as u32, sig.as_ptr(), pubkey.as_ptr()) == 0 + } } /// Trait for things which can be printed. @@ -181,33 +184,57 @@ pub fn print(value: T) { #[macro_export] macro_rules! impl_stubs { - ( $( $new_name:ident => $invoke:expr ),* ) => { + ( $( $new_name:ident $($nodecode:ident)* => $invoke:expr ),* ) => { $( - #[no_mangle] - pub fn $new_name(input_data: *mut u8, input_len: usize) -> u64 { - let mut input = if input_len == 0 { - &[0u8; 0] - } else { - unsafe { - $crate::slice::from_raw_parts(input_data, input_len) - } - }; - - let input = match $crate::codec::Slicable::decode(&mut input) { - Some(input) => input, - None => panic!("Bad input data provided to {}", stringify!($name)), - }; - - let output = ($invoke)(input); - let output = $crate::codec::Slicable::encode(&output); - let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); - - // Leak the output vector to avoid it being freed. - // This is fine in a WASM context since the heap - // will be discarded after the call. - ::core::mem::forget(output); - res - } + impl_stubs!(@METHOD $new_name $($nodecode)* => $invoke); )* + }; + ( @METHOD $new_name:ident NO_DECODE => $invoke:expr ) => { + #[no_mangle] + pub fn $new_name(input_data: *mut u8, input_len: usize) -> u64 { + let input: &[u8] = if input_len == 0 { + &[0u8; 0] + } else { + unsafe { + $crate::slice::from_raw_parts(input_data, input_len) + } + }; + + let output: $crate::rstd::vec::Vec = $invoke(input); + let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); + + // Leak the output vector to avoid it being freed. + // This is fine in a WASM context since the heap + // will be discarded after the call. + ::core::mem::forget(output); + res + } + }; + ( @METHOD $new_name:ident => $invoke:expr ) => { + #[no_mangle] + pub fn $new_name(input_data: *mut u8, input_len: usize) -> u64 { + let mut input = if input_len == 0 { + &[0u8; 0] + } else { + unsafe { + $crate::slice::from_raw_parts(input_data, input_len) + } + }; + + let input = match $crate::codec::Slicable::decode(&mut input) { + Some(input) => input, + None => panic!("Bad input data provided to {}", stringify!($name)), + }; + + let output = ($invoke)(input); + let output = $crate::codec::Slicable::to_vec(&output); + let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); + + // Leak the output vector to avoid it being freed. + // This is fine in a WASM context since the heap + // will be discarded after the call. + ::core::mem::forget(output); + res + } } } From 0e5b1f2cae510f91836d53fb78a7c6b3b7285ea1 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 9 Feb 2018 14:17:19 +0100 Subject: [PATCH 5/6] Update builds and fix up test-runtime. --- Cargo.lock | 1 - polkadot/runtime/wasm/Cargo.lock | 1 - .../release/polkadot_runtime.compact.wasm | Bin 75751 -> 75751 bytes .../release/polkadot_runtime.wasm | Bin 75800 -> 75800 bytes .../release/runtime_test.compact.wasm | Bin 13991 -> 14152 bytes .../release/runtime_test.wasm | Bin 14116 -> 14248 bytes substrate/runtime-support/Cargo.toml | 5 ++--- substrate/test-runtime/src/lib.rs | 2 +- substrate/test-runtime/wasm/Cargo.lock | 2 +- substrate/test-runtime/wasm/Cargo.toml | 14 ++++++++------ .../substrate_test_runtime.compact.wasm | Bin 31904 -> 31904 bytes .../release/substrate_test_runtime.wasm | Bin 31984 -> 31984 bytes 12 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aae23858ada1e..a2d998ac4495a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1521,7 +1521,6 @@ dependencies = [ "substrate-primitives 0.1.0", "substrate-runtime-io 0.1.0", "substrate-runtime-std 0.1.0", - "substrate-state-machine 0.1.0", ] [[package]] diff --git a/polkadot/runtime/wasm/Cargo.lock b/polkadot/runtime/wasm/Cargo.lock index 1ed330a400aca..df8296ff092ec 100644 --- a/polkadot/runtime/wasm/Cargo.lock +++ b/polkadot/runtime/wasm/Cargo.lock @@ -649,7 +649,6 @@ dependencies = [ "substrate-primitives 0.1.0", "substrate-runtime-io 0.1.0", "substrate-runtime-std 0.1.0", - "substrate-state-machine 0.1.0", ] [[package]] diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm index e56ad51f9a1de40b9ae8d68e0d63a9c4689d19d9..9caf937719dc7f57728908211949ca18015fe749 100644 GIT binary patch delta 2846 zcmah~4Qx}_6~5=%#!g-w9@KFHiOKVG6914mq!R(cPkEtXo zx-G?C7gb0@Q?|SHrJd*i(PAL$GQG8RtF%oiErHQtO_7GCsEb&-T2t0pYS=(ix1IN% z?U-uQBE6h@&Ufy2e(t%~pWiZme#PLkypKKtFv2<-4m>^X;{}!Bq)DWz95IRc ze2d5nwl-_7uv8i~b>jb7L#LGX95v}N&zMBuTb#=fo}!%sk!CA(swpZGl`2m87FN+% zYWr`1@vh@z=+82{+x6nQ!5DsGBFKmCswo3CJXkL#Nk3_#N!&?K@yf z8Qb0r)lGUuqip?-IW8-L;%-`(Pa_`X;FF&ip^f`iifrr7e;L-BG$K=6g*vArs-AK6i z_){j>r@S#F(E1dw`9a@`>H7ISNkvrycHnAp1USC zoGQ~AdtMhanz)lgOTus>UGywDCOXur9cqfHE9y|IE)h^*)yln}9R`yIvcTz;(8`8R zd+`xaE}XWe?Qg&G@6BJ^Za_v$r&xqkI8R1ACZsc}<7B{bLe(ggG@<4YN-(T)_vcHr zd-c_sA=t~lbM~8R@psNfyiuQ&F!Q_da;%bK4>WR>+5`~Zdg7{_*8z=8f85o^6S?(HTvji`LT#ZT0NMdOC-zCYEz4FLx)u zMc^B(kY`}wiyLXwrveu**>m*ssfQtU_ChVai5psNGuph1rOjASX=+N@k;_lgt8RAn z@{4rZ&GwJ&T)WsJJ@=LA+?@m)g0>0mzO7X6n^vtr_yXmRW7D))d&bb?C{EleDM32b z=7QSX7Uj3UybDX_)D&8k>%Yp&$r>0v4)#v(k@Cem?cl^TQuCz4n1e`?0FAH2?#Yko*5cdq48eCPjmeLb@*{9XB7vev-< zweTe>_u0bTq~gBuSsv_FtiS(gh4P1gu;t;XU$6+dd<{Nj+7h&7%rE2$`f^Hj(3hir z!ItvXmKle%Z_W{+7bW&qJ_ol9AiVWy zK0LZSY(CO6Sl1isA<}}2D~dcsh?@`+UrxvhlpF9f;zy)YWn57+qFz+e=(Y@c9#H|& zsw}iIgH9ltL`Gj0x?M-tA@y__XHl~V^!C;fX$GA~&>4|Tpr#B}q?`jF(ullSgiSPF zE`L`92ThjCFN@%ZGxBv29;WdM`705sAR@1JL1j4V=FEM;zPj$NZi4rav-I@`>W+7G zVX&B+Gjs*fJfZraxvQt0;Bf0oUvH4$ua&L@Ljg=R?G{A0nUvDqhi-EzWiWt9(#`RK zu23*=_}juEPfsY+b3AyMND&Wq$wtU(ET=-4EPc0jQo-d)<9go;ewTG6CO@$ zJdx%-oT;w8=P(9YK!Oq6s2)okr5$Ayza{u#Q@rv{0XFZ6dpUbwsJ%Kg(B0qhtzb3Q zb*!WNh(FXvq=c6)+@#LWWNLp9*LrnvL}$@jn}r_Dpb11Hh}LAG9T_yTnyU%)^#w!y za$`AEIVM;C?*eD#k#g9GlW?;fDyya{xuRaosWgkXKf^m)naaPX8|zQXG%*DAml9`$p4q)^8$AY7;UM6;}~ zqh*a|jiEJ(z7O(EWm)SoQEvOWqH**s!JToGH~{225MtGsl4<^BsQw5yIW%*mnsdqD etAG-D$PGC#F2CRgCyiIXXon)2td_%A^M3&4;>MN$ delta 2812 zcmah}eN0=|6@Ta2jtvjPOA5w(#m~<+{wNqo6+&pX@*tpQ3y1-QvL-1GcnO37GauO| zR#=BBG*y$QyY;zk)Y5KAtSukTUZOCmQXOR-G+7rWO%$l5ZMP1zDDZAaBVwsYSz z;7prl>G_;{e&_p~dq28m{OFc3Q9yDn**xS~@JDh1a#a_Z2k27I83KgdbJ10k2+ydW znO-CGLzASjO+@`Hd%c=`?4l2!{2QdyJNr%>pjVx1@ByCA%Vhwo^k(CsqK{qjJ(p|| z9Aci2qzsaQ(KUn6LmQe(AfFy;iv2$w)xZBKfLS`&eB}9sfFLpt^CpQf8Z}9|LboJ{ z`CZm*F;9+}hVVaS7?L+MVJGUdeOol{GUa8PsEfa}ju2zW9P0L#x`Tq@2 zds}V;iM#2Zr!O<|_oq9=dADp9x`j4o{0^}SIoo*=J;@0e@*6mzjXr8cGA4Y7J8%ALI3>ay0Umcc!J~Qq)t|Kl5lIn z7_B>am(PfxdRzD8k_TS3@3{|*&`X1T@4~A3kG>Qe%B`baH8_;GLmNt=kIaI^i%91| z=y6&}1LNnQ*~*E$U_eB)3I(*QzYphnrT=FJ=u~QWC{QPlIRL(*{`mMyIku?Q38!72 z)fo9@5v%B>HIp`5D=+MI7Ro=;B&eZ7>fy;#%Zy7AR{Yka;6e;Y`2rsf|E>7Eh?-_%{HI zGcqT0K4O%G6OyTx7)6u3)fbbGaJV-}EV!z_{N4`=w=koR2)KPn?1&wivq1r!oa@HR zpnfptHl%W5G*B zBp6&h^wt1~kAUqMy-Z%=hGff-RD#NwM(S-p-c^5or>$r}xhm zvD=>=ccJV1XYEF@SSV1x6u(AD)T3H|9wfMHj*D&d`{xVcHhuei7m2y4c(Ii>UuY)l zE{**IvI|Vw3$66q7xzPqzI$;XOTP<^Fin%^YstK3R%{V+NrN2I7EE%q<9a&MYe8=& zo+Gnv>bvv`iMna>QrqsWcIkN+Z{+RdaBoodj<(>%Y{9ikMNY_9n||?oQlh;ZsBs*d zyi;D&n+&YU-RiC@pTM>SmO_tOc{L}CyHSeVlKsFMboJU!=utns#)CPn zOtY6tsNwpj4E_8%qO|x|_t^4S-uqlLF)dx7ORtx1)7wD*`g$`PQT3@K%p!WqR@UP* zV-+?Zxx95vZS2_*%{YVWr(PwnP7lBN44cH|HyZ#F^pgc?$Flxhq|&d3M|gr>TB^pE z;ZI9BY+Co>#Pz&z7SEQERtTj;YjZbOkZy(ZqD-Rj3{_&r5$4o3JTEuLj z245tN1&xgd#cWY$7ny?2&IiT(w64Z(Ds1Scg80V#r&P>$+ISf~+P0vymYA#D%Z9wi zFh+hFTn=gvN&IRq54Q{;T)mSE`*+M(#wSAcCkKb?IlP9vVK_X(;RDN?nRs}#pTqsp z594ED4qssX5RQa6IhsBUhfyt-K8%c`+Cus;6+$GAhhw8t^<$AyPENRad*U&U^K$q@ zI#YynFMdWQke3mjMX{fqkTSFhKOIdW+K$r7476nvT}MiIYa3mZW_?CEdG!hv- z86M!|2VUMTV2e93D zeb_ZLWPMB`wIPk;w+%lWpkHYd;S1eKKX1z{11Ef9aO9X)!>XS*V{P?Qp<&F@&s(&V zzd3=eTJvu?XQ?sgC$^j`=iE>-6AS1w4vj^yApx|<^*I`1TNMvrb!fyUo=Dq=k=LtB zBD#Xo+6?sgCc28~7@{>9=-?*$Ai&pz#>c~v38lpYm1T*?|962aO4I{SLR9&U2P!HT zD|mY!=H$rmJF)3^r6QgG=m_SYQat70-aT8%+f!)b$uM~ld3`fumAsHZR6@yK!f`I7 zxa`Uc<=};sa;6*tGxI@S7%SAVvk2E~ICkBx8w1LXryht{2<7?l<$^9sWR<_ELc!p@`95jt6s5zousOi H8Lau=btt?8 diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm index 6341c45abc7cadb6bc9a36ffb3f1eb54d5a65db3..0dbb6b8cf5f202cd16ab85a4276ec901a2dfff78 100644 GIT binary patch delta 2830 zcmah~4Qx}_6~5;_J9hH&^9sgE2*KAcKmH+c8dTEawu2WMR3y?yAp}ah7B_g15R%ME z$tIS?3`%d0MDg+1j1= zo}HL#(;~f`bI*6~`T6d-*OMvBWXckE(o)f01ZAZZO2LkQS}i>buuuCy@KgQ^y9~QD zSHX*v#y$KqD>GKxsOA!dW;)~Hwf9|vj8=C4>jLc7e!kTUxcZ|~4Up#lYJIG7#-qeN zid}NCGA~^aWI>l{LF(dP-Btx__;cGP|DTVx?}04<6a2-t$DfG%C8kF>Zk4GnC#-U* z)G15M(N$8!%9KfKAO2qu`jnjKq}9whWtBndbl-t+lJ+s8EHs#*l2j&os1%ht`JU}A z$A1H~?`)q3dcB4pdhlnuSihr_z3)+MQm53eZ%)t>srU|&VI(CEeLjIm?R;X#PDpAW z?dX7}hs>(-(xwHs(ZPb?);F2Kl!Os;j1RW&;#*s{^IPpM?$~)x^^9M-i-=0f6lqf| z)fmPY@7=j5=4H_Kw%=V!qh9UgqrbDjZvMpnw;`svLJI(~@Ah=*e8*hInUs5J6l9U1 zJPvp!M|#S^!N1kB9}n^4p3?$6qMbZ=7r-9v(xGn`x6T>Wxhs@+4MjP@kb&LL$dw%> z0^Q2WS;f<=^4V6>Swf_TMJebmSH5Ss;1<(Yd;Y17U|;eYh2P}KqaE-FuN)n~497>m zY{h&Zk1?7{Wcy+wdq)YyM1{=uG_&U?D$FIaAj;3ZC%2ubHHdx96!V7oQz2b9 z4$tJ8ULc3%YQ5`fy~OO@tk%0;$53F`n(v1PfZYamVB6J7iu5V=KDi2=v6Qnf`S3~5 zuD(PTJd-?OM_O~B7p^ICmT)Id7RDp4I0JuIwq9>n28ME0Z#ywvslPQ>rfV>4V!Fb@)=Cbo{M8FoC*Z@^1C+)*y!lKA-xqVh zbv_vDqVuL<&8b$JFx6A2F6wGK51uYAdRW@Rq_z?$7I^&By)@=GkPlBg3(XU0g)#0v z)k5Fbx9oDv8#6DvI!Xw0We1Z_o_UnM>)|)fe4oyF_;YVOv}uJmvx&92Cfo!k7i|e> z!w737K{VTDL|UUsXXj{@@noULA!K{Kk~Y}}o$XHT^EYom!J=M5m-gvTiwpB+#LR;v znq+CNU-p0-%gEkw6UH(Oj`94caemsX2@&+sjsME2OP+jdJ(ByEx325PKfHa*Fn)01 z9AA7d0BLP?vY6tV&Mx1>H!ppn34d=9c+-u4;NqXW?vsqR_wt{MVXyY3E5EMP#G8E8 zcr3u|tVr63&z7Nrq0R(Y5i`}K?qI5u0p`g18tSq`&Nmal*X4^==5RYj1tU6FpsW`w zm06k8LPS=^oYE$&0kb)>ZdU`wEtxsLMTFlAz|NPI!2_$tZ3hRB28SYpL|Lj4E266j z@eo2%s|cw?xfwqTendG@D^_$M>cd42-L{OrhA2a{F%R9oj3yAxU_^f&y2C{8#?W)M zqFt{dG&B?>$~-zxpfe)NiQ1P#Me9TWqD-g*GTcW~b?O^3RMSkI`db+SFr|Jf!$z8_ zR|7TB2vPO18fX}gc|_ZAcsMxFKS1#Ai}vA>P;j)jACt{^M4>;7=7jEp=KjGRf@5wj zhKIrgf1}JrI1<8Ab8caDo6jx=hS6;?yEqy`B;ygKP=6#GI`DP&q<1h985|8CAWGDW zEIA0-fbDdkT!S)+pMW1xrqs(da3`eHTQ#tDQ`##U#1rMZSF{Fu1`lA8B@8fu8}(yJ zp>(2*;a7kklHyax8QkBU@`=vjNKaGbsezH+BjG0O>u~SD!9Zk~C~2Q)Lu2r0s2|Jp zAs0F^UmHO#Zu(Y&OIVs7{P0R}^`ly-8jtx!V`4%>5#-Wua`|M);L?xX;U;~4X0!Xl zsGHrT5M4lPOCEY?8BHS^MYK5&?OjHr8^q?&@NhUXqK?)B+9J%W<7Wyqh6^8|M+A;l%nM(_7jAIhEFWddJZjj8rB)KX3+Qcc*#6#a5>A> zfLIYn-*vb%g%SsV{00aqF(PGh@yl>|5;s*F=4g}pf(L7htLHu7rl}^i*$EXi)1=0+ G+y4NdKEc)i delta 2805 zcmah}eN0=|6@Ta2#)b#@C2@>_fUlno{wSCvN@zpUg+~Hwv_M%x14-93F1QJV05cRe zEgh)KCRDX4>D~6cE^0};G*+twx35)@R%y=KE;Q3Ncbhc+NGoefD^%qVs%9NhvToI^_x#THIrqfV=6Kqibdq9Qfe3aR{zx%EvF0Ne0Upx+Yzh%_)62fHP&lBu z^IjnAjz!jwyNKo%O`FIqFZ1pA3^JPi{_`d{q`lo30K9#yQ~=DgJ5Apyz2#MIdKH`G zruG2Im}C>D3nr* zy5%~MgpVD2;4Mxn_w1vSKE*0^N)K}7cSw;`xJIOCNl8Lq&?HC?vZ+0LVOINSPdn7L z8d2rAT`+m{3^FDUS2Bz#OI~jCBpYnq&l;Or*zHy~bL_pZA`z0d2%?fQ$h<+4KAjn7 zy?bwnIUcmG)_aS|qF+1n@E^=@h&_7bH!!ccBN=SU^W7c1-U+wflac_L09m9+CjonM zqPqmvvmbXK!6ts%{hA3nv@=Jy0PNF#ckCyHO;dWt9+xtqACzY(MtkUoa%p>!i8Rs@ z>UxrvKGh`bD-xtOQEKp%C_mLjP{okdPCv03Y&QaW;0tVSv>iHF>DT~zm>he=g8n`| zNy)M!>(?FG+KUJ}%BR*RsV&!0{<0(MvZDvayUjb79R;~RX`3Lv2w)yp1VsoCvmzar zE%n4qEy`*|ECC|mz#y?5^5<93T>o9TFE}&z*8&tzJEK0AGRj)v2Jh`k-7; zPi!=xOhI3c$pDTi$b}SX9E+^AKGR{v=k+q{w6RCdm2wB!CsM(kZ=gufx%TY29-w!D z?dZKiNeg|7txqmTVGLuz@iJYwqN~w!(D1Tp$e|zGE{ocySd8K=kxTD ze*V>yu%Fp4JkAGu?7~Da9#R&p(m|ZdN@e!0R4M~x7G$7EQ+!@%qLlA|?FldNi_1*Q zr1jbl5?2VBs?xskdYIrEXrF0gzrI)k*V$h#c96J_eS4;rjb3UdOJ4n0Fw;z?Irkv6 zvDasIL!2$n^yC{aq6tp2&o9=KNnNeXCKZ!LC9aR3>~1d-s5?6&>`wAwGT~zf-}pJ1 z^0Cj~XxqA41S9UU<+wcp4iWO+fo8N&CYeMdQz}RfZRE|rl5%}}pu{n(c%`ynR2+Eu zI<@Y%{{eZ^JcKUo@a4k%a`cmZPlg|?n^7N+iGBF)IxU`R174)My>)E~cKC(>W=vnDRFwd3(Hwb24; zGj1pS2>LM*rUleE&T;|cI2opntgL=q5m=VZgmH;{ol6}ar>LMs=PHzyqQx?`OZ9?C z?bIo4#Td|=BP%u+*0)UJ@=g){WCH23-446gj@yPuA`N4`{S5-XQPI>N9T0HsidN3< zAM6%zo{Y=zP*lLZY+RzTh@ebmFa1#zi)Swb!zebLy^KZ>N#Nz^;Aq28Y*0{=KGBt2 zCkTE4e@Mqmk#57!%o)lY!V}02@*7f)?!wPNGl;e$w>AfDSwWW&rHF=d&^;^YRF!Ds zQACD@Fx7aK=t`{>gnKJ;gj-jHlT{*sprq7%8Fr9~YW15kRFLUv^>G=(kXC;t!)7w! zS3i)U7Lw{eWvFSI_hV_I!wm!dSiy{6lp_7HXr$-+^s&KMY;Y{vBPff0(Iq(q;U09< zh;%*DIs8ocVL8=nUf2jJ^|lwvw$2AcJ!wI?9uO@J-GeidJMcj7It~%Ajb|L;l_f z)?^{LYMh70jUQh%u72c$^6_}cXl7(6hHVa^KF-Nw5k5YN5N3x;ytT=!eiY9}b}2;D z$gR&okFB8dhz=pTDF^LcK^H^frpWMcG&Z7+RY7e<@}B>lU|PLW1>0dt{Z|##)Xvt3 zt|J(eJIC(GirsWgHvYi@j6b6us0QEGiCWQ>L6xc;m8bA*j9|Q0l#+eNk6aFI-%n#64X10}b! A4FCWD diff --git a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index 1bca666aa1c9f94e13be0ecefc8ea82c7875ef4a..39b6f737efc2312f442206f6204d317487855cba 100644 GIT binary patch delta 2730 zcmZuye{5Sv9ltxj=U->Xm!!2_$89cYk~v8mr|If7EVR9_j-oEKngr9djl@Y_TDz_t zoL7=osPP{aAcUq=mkov{Et)b>U}YHzFi@EyR&5n3lK&{ENC<)y34{iik^M0-O?;l6 zw3*ar-+kWq=Y8+{{ocJFoWGTy``ivTJ4-K*cxG!4onZvw!O`2yvU#dAtTSnb-7sIn$SDY&Kw9Q}*z9+D;E=@+4SaC9U(5_Qm0%WnU=f zNu9sSn@s03Vr5s;d?7!b$&Zt;`+Pc= zD~yp{#zfJwNX!?cL=o=kZjSG1ZQAXhA8P)M{$X=`NVI_8Lb(!(3!jQBQxZvqU-c@F z@JW{z~~_SX?qY%Xxtj`owe_d^M=cAqOP_4*pxd}Kpnu%*$|nEMnzzNF-Ptxsxz4pc4gR}r z?X$mN%$Q}D6~a$2LzU>cRx`y6c1+SBQCr)RrV3%^NRe%IZ6m$eR%4TN zAONLg7JgTWh{o74=O?LZ9tsl4B!RO|LLQlgGi+XoDh0v-;oTyTL`Mm}sQL>T3eu`i zXvnPNHWCBvicNw7%m6ARi}~LqI{?)#X&z!T zEp7)UTRh6yUWsOr1?iFQLHUg>;W)yL*x34_obsHp*q!?P)khBHL7=+=nS%e!PN(( z#SEC79YaYBkJ!^UOwu3iczV*%e$#ueup12Xv^|Pp`*+w znQBfCGu)zcBNp9GMt#aiv4;US^@oi~oN)$>mf_-F6{TR^@EH>YcG8jkn-8 ziZW3&tdD<-p*!A+ zIa`nc=@$v0UmD^eeRI#t=+Sg@-)tm?_FihL_U3%kW^cOCf&5zh6j25@DnUVTL^;Pb zKRjg@is>^JQE_f&@{<>AqI$XK9``VJO%w`54RF_J`jT_{xo;wq&rF@Q#&Jj9#^s4C zRTj>HSVNcF`jbR*wwVyJ2ZN}2%A+HA@ncMGVk^+VAnJ9>jZ0P${+B3s74isU1uwYq zu@dF=W9iBCSjN663%J`Sa)oJv=tRF_+mnTD|6z#q=~j z3S&LRDdHTO*E)Z9^0tc$0rduGA4L$38-lLj(Oz)7L5u($?kP&h&Z=}{o6SMkB&ysw z{p+p>UDChr>V0g@;Ptu8=vbj>B@2_zXRW$s$>ioUJv}|o5jAJ>s4!6l$JR|q7%&MM zi(vh0CeP{r?8^-zVQwxeSi}kNIxdddz82kFmZ4q;?i$cZUj>LlZgX?f&F6Gw-&LgX zj_1CcH{k}lSZCeCqb0mL`&PActU{d#3+Fsz|%mOlMx`o-nQ7H{^!15Meh3U zuk-f3bt?Mp{gH+_Kj)(tZA;?YYt2Z4GxE3n-FwS^?v)8gFa_S4pSwF{VM30edVWp; zC9eO_l^j~)4@_#A^SbI+T@HL!TKRFAfD_IQhlC5xMW>uTYvtusE;E+NpK%E7{&x4)O*$dcl_V*{!5xoE)sfX3|qja0%F2wb=;r6Nuo% zE~0MKad8@g9T3#ti=eD`_wK5z)N%J#f=eO&SZ~L3iyhZaoTu`w7>}ODx=yE+fS>NPa?Gi4wAA##6wd2sQz!oqe&0|u delta 2594 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 H`MLiAI(B2s delta 2532 zcmZuyTWDOz8J;=k>~+p+N7r5JV$H5s^2)MTmssmd(#Ye+j%n;Tq>$1&jps+*8{8Xld9emFR1?zyCB97QyFsQT=%>>N318uh(y| z?N8mN&86D>bfGvj;+#uohNd$Y)0r_6bWb@`qq!NvtDC7Dsr7)F%D(E5I!zUvBB^&z zr6wn{qolza&pQrjw2KZLjirjIp>&3H)>e)smY;DNmsBc8JSF7aQcV(2a;q@pvn|4W-nFG-H)96`VW%5^;Nku);}=N zcWCHUC!ZdlA^X(JMoUA&7obEE=ILn;?PzNX`){0#sJ-^fW{BNXKetace@!QPD0z|) z;gvt05I(s*XDT#{!0JF?pXvT(*lDM+B9#v)?i(bs8N{UUmZmfwsvslP?r>7x2?bh%^0 z6o&BecKBH}c?9s0i9C%ev%OXS-1T(*2k;se6czB|3UT0~IuP4weQx6lKa3rv8|qpt zOy|`5v3*pif5hIWLG@0@^YpH|*AW8~=sXtM2qXn| zAFnhYR1=+htm{G4WY_LjXv58Bov*NkpYHrQHi#^cSkn)2iq8dCxUaUwS%9x2QoMxsA9GML}_!%^yLJ zRR?zPR6uv_3vw!eic92#Bnj>`!RfKXBq%9&MWKsHkThvDpf3R3CEPX);1l>2oPb`3 zFb0fp1eyZ|kMvrSKq4>>mav3*RQ&V`YF@2iS=S+o(ywoAQ2f8E@A;k#Ht6B8Wmpfi zEnC%FzTcr^&-(i*U%KqStgG-J7Aq~%YUh^eR_9=EVzC>or-`(fRS9rHq|H2d(nR(G zI@iFg%T7K^WSE)Rj6-BAGx7cqDHy}^H&iHQ^Qm*-_cB*HlbbH;8ZgfTdIb^2v(R6~ zrgkKCnaDN5eB_h)8|(`}?dUWmq!CEu#v?XQz$RX0XVu5uA-bUc(%t*an#F1-(<7tVywj7-={G!) zFA!O=nCna;kvL1_tc!(-3zdd#1=s`}1|kR|yzOF>>JPmq)Zs+zD3Mp(jISe*PVzV2 z?R(6-nJB}g2J9LT3S=FKhCSlyJvWd&B zE(yE_>RzIISJ}_JBCZ7maBF_%?h@H?F^q2c83k1Q>a*^i(gJ&IVatrwRR2+nr@kYc z%$SJ731gN%!UbczOI$qfWJF;yJ(|v((~c{QHHmaVWT%Td)JS$ZGlo+&=$y@rL;}-i zGv2GOh>ruqm<58dvzd2pize~|o5j$q*l{91hkgzMUBjywQ4|L175lMC&jlD?fU9ooDBRjF+LVCvP1XsJglicH2qlp_3qM(xuzZrBF=eiv^J? zBBk{p3sh4@-M6SpP_6X6MAw$u`;(N;F1_@`NlMq$yZfKT-^Z8xuhH_-&jvD7+-zpy cBZ#X"] [dependencies] -hex-literal = "0.1.0" +hex-literal = { version = "0.1.0", optional = true } substrate-runtime-std = { path = "../runtime-std", default_features = false } substrate-runtime-io = { path = "../runtime-io", default_features = false } environmental = { path = "../environmental", optional = true } -substrate-state-machine = { path = "../state-machine", optional = true } substrate-primitives = { path = "../primitives", default_features = false } substrate-codec = { path = "../codec", default_features = false } [features] default = ["std"] std = [ + "hex-literal", "environmental", - "substrate-state-machine", "substrate-primitives/std", "substrate-runtime-io/std", "substrate-codec/std", diff --git a/substrate/test-runtime/src/lib.rs b/substrate/test-runtime/src/lib.rs index b5be15fc2317a..3e0f65a2b4048 100644 --- a/substrate/test-runtime/src/lib.rs +++ b/substrate/test-runtime/src/lib.rs @@ -23,7 +23,7 @@ extern crate substrate_runtime_std as rstd; extern crate substrate_runtime_io as runtime_io; extern crate substrate_runtime_support as runtime_support; extern crate substrate_codec as codec; -#[cfg_attr(test, macro_use)] extern crate hex_literal; +#[cfg(test)] #[macro_use] extern crate hex_literal; #[cfg_attr(test, macro_use)] extern crate substrate_primitives as primitives; #[cfg(feature = "std")] diff --git a/substrate/test-runtime/wasm/Cargo.lock b/substrate/test-runtime/wasm/Cargo.lock index 29ef026e0d771..0d387390319fd 100644 --- a/substrate/test-runtime/wasm/Cargo.lock +++ b/substrate/test-runtime/wasm/Cargo.lock @@ -626,7 +626,6 @@ dependencies = [ "substrate-primitives 0.1.0", "substrate-runtime-io 0.1.0", "substrate-runtime-std 0.1.0", - "substrate-state-machine 0.1.0", ] [[package]] @@ -646,6 +645,7 @@ dependencies = [ name = "substrate-test-runtime" version = "0.1.0" dependencies = [ + "hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-codec 0.1.0", "substrate-primitives 0.1.0", "substrate-runtime-io 0.1.0", diff --git a/substrate/test-runtime/wasm/Cargo.toml b/substrate/test-runtime/wasm/Cargo.toml index 93886c1f3a5b5..a40af49c33059 100644 --- a/substrate/test-runtime/wasm/Cargo.toml +++ b/substrate/test-runtime/wasm/Cargo.toml @@ -7,20 +7,22 @@ authors = ["Parity Technologies "] crate-type = ["cdylib"] [dependencies] -substrate-codec = { path = "../../codec", default-features = false } -substrate-runtime-std = { path = "../../runtime-std", default-features = false } -substrate-runtime-io = { path = "../../runtime-io", default-features = false } -substrate-runtime-support = { path = "../../runtime-support", default-features = false } -substrate-primitives = { path = "../../primitives", default-features = false } +hex-literal = { version = "0.1.0", optional = true } +substrate-codec = { path = "../../../substrate/codec", default-features = false } +substrate-runtime-std = { path = "../../../substrate/runtime-std", default-features = false } +substrate-runtime-io = { path = "../../../substrate/runtime-io", default-features = false } +substrate-runtime-support = { path = "../../../substrate/runtime-support", default-features = false } +substrate-primitives = { path = "../../../substrate/primitives", default-features = false } [features] default = [] std = [ + "hex-literal", "substrate-codec/std", "substrate-runtime-io/std", "substrate-runtime-std/std", "substrate-runtime-support/std", - "substrate-primitives/std" + "substrate-primitives/std", ] [profile.release] diff --git a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm index 8d1693d8f8cac9ae16a757bfa2fd46be453596c9..92d39a3789bb5ac33fd2ec72a557ef177dc9cc8a 100644 GIT binary patch delta 83 zcmZ4RlX1aM#tmB;nYr27H}7EFpw6f}Ia6~7kW|vrVbtC1uXUf1QGc_(&NML~bz_+<8GgXMub@GSm4FKFuAB6w_ delta 83 zcmZ4RlX1aM#tmB;nc3O7H}7EFpw6g2Ia6~7kW|vrVbtI3uXUf1QFpVx&NML~b Date: Fri, 9 Feb 2018 14:20:48 +0100 Subject: [PATCH 6/6] Fix warnings. --- substrate/test-runtime/src/system.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/substrate/test-runtime/src/system.rs b/substrate/test-runtime/src/system.rs index d6a9426538d48..82a428d458993 100644 --- a/substrate/test-runtime/src/system.rs +++ b/substrate/test-runtime/src/system.rs @@ -131,10 +131,9 @@ mod tests { use super::*; use runtime_io::{with_externalities, twox_128, TestExternalities}; - use codec::{Joiner, KeyedVec, Slicable}; + use codec::{Joiner, KeyedVec}; use runtime_support::{one, two}; - use primitives::hexdisplay::HexDisplay; - use ::{Header, Digest, UncheckedTransaction, Transaction}; + use ::{Header, Digest}; fn new_test_ext() -> TestExternalities { let one = one(); @@ -153,9 +152,6 @@ mod tests { #[test] fn block_import_works() { - let one = one(); - let two = two(); - let mut t = new_test_ext(); let h = Header {