1use crate::{metadata::Metadata, Config};
8use codec::{Decode, Encode};
9use primitive_types::U256;
10use serde::{Deserialize, Serialize};
11use std::collections::HashMap;
12
13pub use super::rpc_client::Subscription;
15
16#[derive(Debug, PartialEq, Eq)]
18pub enum DryRunResult {
19 Success,
21 DispatchError(crate::error::DispatchError),
23 TransactionValidityError,
25}
26
27pub struct DryRunResultBytes(pub Vec<u8>);
29
30impl DryRunResultBytes {
31 pub fn into_dry_run_result(self, metadata: &Metadata) -> Result<DryRunResult, crate::Error> {
33 let bytes = self.0;
36 if bytes[0] == 0 && bytes[1] == 0 {
37 Ok(DryRunResult::Success)
39 } else if bytes[0] == 0 && bytes[1] == 1 {
40 let dispatch_error =
42 crate::error::DispatchError::decode_from(&bytes[2..], metadata.clone())?;
43 Ok(DryRunResult::DispatchError(dispatch_error))
44 } else if bytes[0] == 1 {
45 Ok(DryRunResult::TransactionValidityError)
47 } else {
48 Err(crate::Error::Unknown(bytes))
50 }
51 }
52}
53
54#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
63#[serde(untagged)]
64pub enum NumberOrHex {
65 Number(u64),
67 Hex(U256),
69}
70
71#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Hash, PartialOrd, Ord, Debug)]
73pub struct Bytes(#[serde(with = "impl_serde::serialize")] pub Vec<u8>);
74impl std::ops::Deref for Bytes {
75 type Target = [u8];
76 fn deref(&self) -> &[u8] {
77 &self.0[..]
78 }
79}
80impl From<Vec<u8>> for Bytes {
81 fn from(s: Vec<u8>) -> Self {
82 Bytes(s)
83 }
84}
85
86#[derive(Debug, Deserialize)]
88#[serde(bound = "T: Config")]
89pub struct ChainBlockResponse<T: Config> {
90 pub block: ChainBlock<T>,
92 pub justifications: Option<Vec<Justification>>,
94}
95
96#[derive(Debug, Deserialize)]
98pub struct ChainBlock<T: Config> {
99 pub header: T::Header,
101 pub extrinsics: Vec<ChainBlockExtrinsic>,
103}
104
105pub type Justification = (ConsensusEngineId, EncodedJustification);
107pub type ConsensusEngineId = [u8; 4];
109pub type EncodedJustification = Vec<u8>;
111
112#[derive(Clone, Debug)]
114pub struct ChainBlockExtrinsic(pub Vec<u8>);
115
116impl<'a> ::serde::Deserialize<'a> for ChainBlockExtrinsic {
117 fn deserialize<D>(de: D) -> Result<Self, D::Error>
118 where
119 D: ::serde::Deserializer<'a>,
120 {
121 let r = impl_serde::serialize::deserialize(de)?;
122 let bytes = Decode::decode(&mut &r[..])
123 .map_err(|e| ::serde::de::Error::custom(format!("Decode error: {e}")))?;
124 Ok(ChainBlockExtrinsic(bytes))
125 }
126}
127
128#[derive(Serialize)]
130pub struct BlockNumber(NumberOrHex);
131
132impl From<NumberOrHex> for BlockNumber {
133 fn from(x: NumberOrHex) -> Self {
134 BlockNumber(x)
135 }
136}
137
138impl Default for NumberOrHex {
139 fn default() -> Self {
140 Self::Number(Default::default())
141 }
142}
143
144impl NumberOrHex {
145 pub fn into_u256(self) -> U256 {
147 match self {
148 NumberOrHex::Number(n) => n.into(),
149 NumberOrHex::Hex(h) => h,
150 }
151 }
152}
153
154impl From<u32> for NumberOrHex {
155 fn from(n: u32) -> Self {
156 NumberOrHex::Number(n.into())
157 }
158}
159
160impl From<u64> for NumberOrHex {
161 fn from(n: u64) -> Self {
162 NumberOrHex::Number(n)
163 }
164}
165
166impl From<u128> for NumberOrHex {
167 fn from(n: u128) -> Self {
168 NumberOrHex::Hex(n.into())
169 }
170}
171
172impl From<U256> for NumberOrHex {
173 fn from(n: U256) -> Self {
174 NumberOrHex::Hex(n)
175 }
176}
177
178#[derive(Debug, thiserror::Error)]
180#[error("Out-of-range conversion attempt")]
181pub struct TryFromIntError;
182
183impl TryFrom<NumberOrHex> for u32 {
184 type Error = TryFromIntError;
185 fn try_from(num_or_hex: NumberOrHex) -> Result<u32, Self::Error> {
186 num_or_hex
187 .into_u256()
188 .try_into()
189 .map_err(|_| TryFromIntError)
190 }
191}
192
193impl TryFrom<NumberOrHex> for u64 {
194 type Error = TryFromIntError;
195 fn try_from(num_or_hex: NumberOrHex) -> Result<u64, Self::Error> {
196 num_or_hex
197 .into_u256()
198 .try_into()
199 .map_err(|_| TryFromIntError)
200 }
201}
202
203impl TryFrom<NumberOrHex> for u128 {
204 type Error = TryFromIntError;
205 fn try_from(num_or_hex: NumberOrHex) -> Result<u128, Self::Error> {
206 num_or_hex
207 .into_u256()
208 .try_into()
209 .map_err(|_| TryFromIntError)
210 }
211}
212
213impl From<NumberOrHex> for U256 {
214 fn from(num_or_hex: NumberOrHex) -> U256 {
215 num_or_hex.into_u256()
216 }
217}
218
219macro_rules! into_block_number {
221 ($($t: ty)+) => {
222 $(
223 impl From<$t> for BlockNumber {
224 fn from(x: $t) -> Self {
225 NumberOrHex::Number(x.into()).into()
226 }
227 }
228 )+
229 }
230}
231into_block_number!(u8 u16 u32 u64);
232
233pub type SystemProperties = serde_json::Map<String, serde_json::Value>;
235
236#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
243#[serde(rename_all = "camelCase")]
244pub enum SubstrateTxStatus<Hash, BlockHash> {
245 Future,
247 Ready,
249 Broadcast(Vec<String>),
251 InBlock(BlockHash),
253 Retracted(BlockHash),
255 FinalityTimeout(BlockHash),
258 Finalized(BlockHash),
260 Usurped(Hash),
263 Dropped,
265 Invalid,
267}
268
269#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
272#[serde(rename_all = "camelCase")]
273pub struct RuntimeVersion {
274 pub spec_version: u32,
278
279 pub transaction_version: u32,
289
290 #[serde(flatten)]
293 pub other: HashMap<String, serde_json::Value>,
294}
295
296#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
303#[serde(rename_all = "camelCase")]
304pub struct ReadProof<Hash> {
305 pub at: Hash,
307 pub proof: Vec<Bytes>,
309}
310
311#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
313#[serde(rename_all = "camelCase")]
314pub struct BlockStats {
315 pub witness_len: u64,
317 pub witness_compact_len: u64,
319 pub block_len: u64,
324 pub num_extrinsics: u64,
329}
330
331#[derive(
333 Serialize, Deserialize, Hash, PartialOrd, Ord, PartialEq, Eq, Clone, Encode, Decode, Debug,
334)]
335pub struct StorageKey(#[serde(with = "impl_serde::serialize")] pub Vec<u8>);
336impl AsRef<[u8]> for StorageKey {
337 fn as_ref(&self) -> &[u8] {
338 &self.0
339 }
340}
341
342#[derive(
344 Serialize, Deserialize, Hash, PartialOrd, Ord, PartialEq, Eq, Clone, Encode, Decode, Debug,
345)]
346pub struct StorageData(#[serde(with = "impl_serde::serialize")] pub Vec<u8>);
347impl AsRef<[u8]> for StorageData {
348 fn as_ref(&self) -> &[u8] {
349 &self.0
350 }
351}
352
353#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
355#[serde(rename_all = "camelCase")]
356pub struct StorageChangeSet<Hash> {
357 pub block: Hash,
359 pub changes: Vec<(StorageKey, Option<StorageData>)>,
361}
362
363#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
365#[serde(rename_all = "camelCase")]
366pub struct Health {
367 pub peers: usize,
369 pub is_syncing: bool,
371 pub should_have_peers: bool,
375}
376
377#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
379#[serde(rename_all = "camelCase")]
380pub struct ErrorEvent {
381 pub error: String,
383}
384
385#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
391#[serde(rename_all = "camelCase")]
392pub struct RuntimeVersionEvent {
393 pub spec: RuntimeVersion,
395}
396
397#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
400#[serde(rename_all = "camelCase")]
401#[serde(tag = "type")]
402pub enum RuntimeEvent {
403 Valid(RuntimeVersionEvent),
405 Invalid(ErrorEvent),
407}
408
409#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
419#[serde(rename_all = "camelCase")]
420pub struct Initialized<Hash> {
421 pub finalized_block_hash: Hash,
423 pub finalized_block_runtime: Option<RuntimeEvent>,
430}
431
432#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
434#[serde(rename_all = "camelCase")]
435pub struct NewBlock<Hash> {
436 pub block_hash: Hash,
438 pub parent_block_hash: Hash,
440 pub new_runtime: Option<RuntimeEvent>,
447}
448
449#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
451#[serde(rename_all = "camelCase")]
452pub struct BestBlockChanged<Hash> {
453 pub best_block_hash: Hash,
455}
456
457#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
459#[serde(rename_all = "camelCase")]
460pub struct Finalized<Hash> {
461 pub finalized_block_hashes: Vec<Hash>,
463 pub pruned_block_hashes: Vec<Hash>,
465}
466
467#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
478#[serde(rename_all = "camelCase")]
479#[serde(tag = "event")]
480pub enum FollowEvent<Hash> {
481 Initialized(Initialized<Hash>),
485 NewBlock(NewBlock<Hash>),
487 BestBlockChanged(BestBlockChanged<Hash>),
489 Finalized(Finalized<Hash>),
491 Stop,
494}
495
496#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
498#[serde(rename_all = "camelCase")]
499pub struct ChainHeadResult<T> {
500 pub result: T,
502}
503
504#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
506#[serde(rename_all = "camelCase")]
507#[serde(tag = "event")]
508pub enum ChainHeadEvent<T> {
509 Done(ChainHeadResult<T>),
511 Inaccessible(ErrorEvent),
515 Error(ErrorEvent),
517 Disjoint,
519}
520
521#[derive(Debug, Clone, PartialEq, Deserialize)]
532#[serde(rename_all = "camelCase")]
533pub struct TransactionBroadcasted {
534 #[serde(with = "as_string")]
536 pub num_peers: usize,
537}
538
539#[derive(Debug, Clone, PartialEq, Deserialize)]
541#[serde(rename_all = "camelCase")]
542pub struct TransactionBlock<Hash> {
543 pub hash: Hash,
545 #[serde(with = "as_string")]
547 pub index: usize,
548}
549
550#[derive(Debug, Clone, PartialEq, Deserialize)]
552#[serde(rename_all = "camelCase")]
553pub struct TransactionError {
554 pub error: String,
556}
557
558#[derive(Debug, Clone, PartialEq, Deserialize)]
560#[serde(rename_all = "camelCase")]
561pub struct TransactionDropped {
562 pub broadcasted: bool,
565 pub error: String,
567}
568
569#[derive(Debug, Clone, PartialEq, Deserialize)]
594#[serde(bound(deserialize = "Hash: Deserialize<'de> + Clone"))]
597#[serde(from = "TransactionEventIR<Hash>")]
598pub enum TransactionEvent<Hash> {
599 Validated,
601 Broadcasted(TransactionBroadcasted),
603 BestChainBlockIncluded(Option<TransactionBlock<Hash>>),
610 Finalized(TransactionBlock<Hash>),
612 Error(TransactionError),
614 Invalid(TransactionError),
616 Dropped(TransactionDropped),
618}
619
620#[derive(Debug, Clone, PartialEq, Deserialize)]
633#[serde(rename_all = "camelCase")]
634#[serde(tag = "event", content = "block")]
635enum TransactionEventBlockIR<Hash> {
636 BestChainBlockIncluded(Option<TransactionBlock<Hash>>),
638 Finalized(TransactionBlock<Hash>),
640}
641
642#[derive(Debug, Clone, PartialEq, Deserialize)]
655#[serde(rename_all = "camelCase")]
656#[serde(tag = "event")]
657enum TransactionEventNonBlockIR {
658 Validated,
659 Broadcasted(TransactionBroadcasted),
660 Error(TransactionError),
661 Invalid(TransactionError),
662 Dropped(TransactionDropped),
663}
664
665#[derive(Debug, Clone, PartialEq, Deserialize)]
673#[serde(bound(deserialize = "Hash: Deserialize<'de>"))]
674#[serde(rename_all = "camelCase")]
675#[serde(untagged)]
676enum TransactionEventIR<Hash> {
677 Block(TransactionEventBlockIR<Hash>),
678 NonBlock(TransactionEventNonBlockIR),
679}
680
681impl<Hash> From<TransactionEvent<Hash>> for TransactionEventIR<Hash> {
682 fn from(value: TransactionEvent<Hash>) -> Self {
683 match value {
684 TransactionEvent::Validated => {
685 TransactionEventIR::NonBlock(TransactionEventNonBlockIR::Validated)
686 }
687 TransactionEvent::Broadcasted(event) => {
688 TransactionEventIR::NonBlock(TransactionEventNonBlockIR::Broadcasted(event))
689 }
690 TransactionEvent::BestChainBlockIncluded(event) => {
691 TransactionEventIR::Block(TransactionEventBlockIR::BestChainBlockIncluded(event))
692 }
693 TransactionEvent::Finalized(event) => {
694 TransactionEventIR::Block(TransactionEventBlockIR::Finalized(event))
695 }
696 TransactionEvent::Error(event) => {
697 TransactionEventIR::NonBlock(TransactionEventNonBlockIR::Error(event))
698 }
699 TransactionEvent::Invalid(event) => {
700 TransactionEventIR::NonBlock(TransactionEventNonBlockIR::Invalid(event))
701 }
702 TransactionEvent::Dropped(event) => {
703 TransactionEventIR::NonBlock(TransactionEventNonBlockIR::Dropped(event))
704 }
705 }
706 }
707}
708
709impl<Hash> From<TransactionEventIR<Hash>> for TransactionEvent<Hash> {
710 fn from(value: TransactionEventIR<Hash>) -> Self {
711 match value {
712 TransactionEventIR::NonBlock(status) => match status {
713 TransactionEventNonBlockIR::Validated => TransactionEvent::Validated,
714 TransactionEventNonBlockIR::Broadcasted(event) => {
715 TransactionEvent::Broadcasted(event)
716 }
717 TransactionEventNonBlockIR::Error(event) => TransactionEvent::Error(event),
718 TransactionEventNonBlockIR::Invalid(event) => TransactionEvent::Invalid(event),
719 TransactionEventNonBlockIR::Dropped(event) => TransactionEvent::Dropped(event),
720 },
721 TransactionEventIR::Block(block) => match block {
722 TransactionEventBlockIR::Finalized(event) => TransactionEvent::Finalized(event),
723 TransactionEventBlockIR::BestChainBlockIncluded(event) => {
724 TransactionEvent::BestChainBlockIncluded(event)
725 }
726 },
727 }
728 }
729}
730
731mod as_string {
733 use super::*;
734 use serde::Deserializer;
735
736 pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<usize, D::Error> {
737 String::deserialize(deserializer)?
738 .parse()
739 .map_err(|e| serde::de::Error::custom(format!("Parsing failed: {e}")))
740 }
741}
742
743#[cfg(test)]
744mod test {
745 use super::*;
746
747 pub fn assert_deser<T>(s: &str, expected: T)
749 where
750 T: std::fmt::Debug + serde::ser::Serialize + serde::de::DeserializeOwned + PartialEq,
751 {
752 assert_eq!(serde_json::from_str::<T>(s).unwrap(), expected);
753 assert_eq!(serde_json::to_string(&expected).unwrap(), s);
754 }
755
756 pub fn assert_ser_deser<A, B>(a: &A, b: &B)
758 where
759 A: serde::Serialize,
760 B: serde::de::DeserializeOwned + PartialEq + std::fmt::Debug,
761 {
762 let json = serde_json::to_string(a).expect("serializing failed");
763 let new_b: B = serde_json::from_str(&json).expect("deserializing failed");
764
765 assert_eq!(b, &new_b);
766 }
767
768 #[test]
769 fn runtime_version_is_substrate_compatible() {
770 use sp_version::RuntimeVersion as SpRuntimeVersion;
771
772 let substrate_runtime_version = SpRuntimeVersion {
773 spec_version: 123,
774 transaction_version: 456,
775 ..Default::default()
776 };
777
778 let json = serde_json::to_string(&substrate_runtime_version).expect("serializing failed");
779 let val: RuntimeVersion = serde_json::from_str(&json).expect("deserializing failed");
780
781 assert_eq!(val.spec_version, 123);
783 assert_eq!(val.transaction_version, 456);
784 }
785
786 #[test]
787 fn runtime_version_handles_arbitrary_params() {
788 let val: RuntimeVersion = serde_json::from_str(
789 r#"{
790 "specVersion": 123,
791 "transactionVersion": 456,
792 "foo": true,
793 "wibble": [1,2,3]
794 }"#,
795 )
796 .expect("deserializing failed");
797
798 let mut m = std::collections::HashMap::new();
799 m.insert("foo".to_owned(), serde_json::json!(true));
800 m.insert("wibble".to_owned(), serde_json::json!([1, 2, 3]));
801
802 assert_eq!(
803 val,
804 RuntimeVersion {
805 spec_version: 123,
806 transaction_version: 456,
807 other: m
808 }
809 );
810 }
811
812 #[test]
813 fn number_or_hex_deserializes_from_either_repr() {
814 assert_deser(r#""0x1234""#, NumberOrHex::Hex(0x1234.into()));
815 assert_deser(r#""0x0""#, NumberOrHex::Hex(0.into()));
816 assert_deser(r#"5"#, NumberOrHex::Number(5));
817 assert_deser(r#"10000"#, NumberOrHex::Number(10000));
818 assert_deser(r#"0"#, NumberOrHex::Number(0));
819 assert_deser(r#"1000000000000"#, NumberOrHex::Number(1000000000000));
820 }
821
822 #[test]
823 fn justification_is_substrate_compatible() {
824 use sp_runtime::Justification as SpJustification;
825
826 assert_ser_deser::<SpJustification, Justification>(
829 &([1, 2, 3, 4], vec![5, 6, 7, 8]),
830 &([1, 2, 3, 4], vec![5, 6, 7, 8]),
831 );
832 }
833
834 #[test]
835 fn storage_types_are_substrate_compatible() {
836 use sp_core::storage::{
837 StorageChangeSet as SpStorageChangeSet, StorageData as SpStorageData,
838 StorageKey as SpStorageKey,
839 };
840
841 assert_ser_deser(
842 &SpStorageKey(vec![1, 2, 3, 4, 5]),
843 &StorageKey(vec![1, 2, 3, 4, 5]),
844 );
845 assert_ser_deser(
846 &SpStorageData(vec![1, 2, 3, 4, 5]),
847 &StorageData(vec![1, 2, 3, 4, 5]),
848 );
849 assert_ser_deser(
850 &SpStorageChangeSet {
851 block: 1u64,
852 changes: vec![(SpStorageKey(vec![1]), Some(SpStorageData(vec![2])))],
853 },
854 &StorageChangeSet {
855 block: 1u64,
856 changes: vec![(StorageKey(vec![1]), Some(StorageData(vec![2])))],
857 },
858 );
859 }
860}