Coverage Report

Created: 2024-05-16 12:16

/__w/smoldot/smoldot/repo/lib/src/json_rpc/payment_info.rs
Line
Count
Source (jump to first uncovered line)
1
// Smoldot
2
// Copyright (C) 2019-2022  Parity Technologies (UK) Ltd.
3
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
4
5
// This program is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
9
10
// This program is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
// GNU General Public License for more details.
14
15
// You should have received a copy of the GNU General Public License
16
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18
use super::methods;
19
20
/// Produces the input to pass to the `TransactionPaymentApi_query_info` runtime call.
21
0
pub fn payment_info_parameters(
22
0
    extrinsic: &'_ [u8],
23
0
) -> impl Iterator<Item = impl AsRef<[u8]> + '_> + Clone + '_ {
24
0
    [
25
0
        either::Left(extrinsic),
26
0
        either::Right(u32::try_from(extrinsic.len()).unwrap().to_le_bytes()),
27
0
    ]
28
0
    .into_iter()
29
0
}
Unexecuted instantiation: _RNvNtNtCsN16ciHI6Qf_7smoldot8json_rpc12payment_info23payment_info_parameters
Unexecuted instantiation: _RNvNtNtCseuYC0Zibziv_7smoldot8json_rpc12payment_info23payment_info_parameters
30
31
/// Name of the runtime function to call in order to obtain the payment fees.
32
pub const PAYMENT_FEES_FUNCTION_NAME: &str = "TransactionPaymentApi_query_info";
33
34
/// Attempt to decode the output of the runtime call.
35
///
36
/// Must be passed the version of the `TransactionPaymentApi` API, according to the runtime
37
/// specification.
38
0
pub fn decode_payment_info(
39
0
    scale_encoded: &'_ [u8],
40
0
    api_version: u32,
41
0
) -> Result<methods::RuntimeDispatchInfo, DecodeError> {
42
0
    let is_api_v2 = match api_version {
43
0
        1 => false,
44
0
        2 => true,
45
0
        _ => return Err(DecodeError::UnknownRuntimeVersion),
46
    };
47
48
0
    match nom::combinator::all_consuming(nom_decode_payment_info::<nom::error::Error<&'_ [u8]>>(
49
0
        is_api_v2,
50
0
    ))(scale_encoded)
51
    {
52
0
        Ok((_, info)) => Ok(info),
53
0
        Err(_) => Err(DecodeError::ParseError),
54
    }
55
0
}
Unexecuted instantiation: _RNvNtNtCsN16ciHI6Qf_7smoldot8json_rpc12payment_info19decode_payment_info
Unexecuted instantiation: _RNvNtNtCseuYC0Zibziv_7smoldot8json_rpc12payment_info19decode_payment_info
56
57
/// Potential error when decoding payment information runtime output.
58
0
#[derive(Debug, derive_more::Display)]
Unexecuted instantiation: _RNvXs_NtNtCsN16ciHI6Qf_7smoldot8json_rpc12payment_infoNtB4_11DecodeErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXs_NtNtCseuYC0Zibziv_7smoldot8json_rpc12payment_infoNtB4_11DecodeErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
59
pub enum DecodeError {
60
    /// Failed to parse the return value of `TransactionPaymentApi_query_info`.
61
    ParseError,
62
    /// The `TransactionPaymentApi` API uses a version that smoldot doesn't support.
63
    UnknownRuntimeVersion,
64
}
65
66
0
fn nom_decode_payment_info<'a, E: nom::error::ParseError<&'a [u8]>>(
67
0
    is_api_v2: bool,
68
0
) -> impl FnMut(&'a [u8]) -> nom::IResult<&'a [u8], methods::RuntimeDispatchInfo, E> {
69
0
    nom::combinator::map(
70
0
        nom::sequence::tuple((
71
0
            move |bytes| {
72
0
                if is_api_v2 {
73
0
                    nom::number::streaming::le_u64(bytes)
74
                } else {
75
0
                    nom::combinator::map(
76
0
                        nom::sequence::tuple((
77
0
                            crate::util::nom_scale_compact_u64,
78
0
                            crate::util::nom_scale_compact_u64,
79
0
                        )),
80
0
                        |(ref_time, _proof_size)| ref_time,
Unexecuted instantiation: _RNCNCINvNtNtCsN16ciHI6Qf_7smoldot8json_rpc12payment_info23nom_decode_payment_infopE00Ba_
Unexecuted instantiation: _RNCNCINvNtNtCseuYC0Zibziv_7smoldot8json_rpc12payment_info23nom_decode_payment_infoINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEE00Ba_
81
0
                    )(bytes)
82
                }
83
0
            },
Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot8json_rpc12payment_info23nom_decode_payment_infopE0B8_
Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot8json_rpc12payment_info23nom_decode_payment_infoINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEE0B8_
84
0
            nom::combinator::map_opt(nom::number::streaming::u8, |n| match n {
85
0
                0 => Some(methods::DispatchClass::Normal),
86
0
                1 => Some(methods::DispatchClass::Operational),
87
0
                2 => Some(methods::DispatchClass::Mandatory),
88
0
                _ => None,
89
0
            }),
Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot8json_rpc12payment_info23nom_decode_payment_infopEs_0B8_
Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot8json_rpc12payment_info23nom_decode_payment_infoINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEEs_0B8_
90
0
            |bytes| {
91
0
                // The exact format here is the SCALE encoding of the type `Balance`.
92
0
                // Normally, determining the actual type of `Balance` would require parsing the
93
0
                // metadata provided by the runtime. However, this is a pretty difficult to
94
0
                // implement and CPU-heavy. Instead, given that there is no other field after
95
0
                // the balance, we simply parse all the remaining bytes.
96
0
                // Because the SCALE encoding of a number is the number in little endian format,
97
0
                // we decode the bytes in little endian format in a way that works no matter the
98
0
                // number of bytes.
99
0
                // If a field was to be added after the balance, this code would need to be
100
0
                // modified.
101
0
                let mut num = 0u128;
102
0
                let mut shift = 0u32;
103
0
                for byte in <[u8]>::iter(bytes) {
104
0
                    let shifted =
105
0
                        u128::from(*byte)
106
0
                            .checked_mul(1 << shift)
107
0
                            .ok_or(nom::Err::Error(nom::error::make_error(
108
0
                                bytes,
109
0
                                nom::error::ErrorKind::Digit,
110
0
                            )))?;
111
                    num =
112
0
                        num.checked_add(shifted)
113
0
                            .ok_or(nom::Err::Error(nom::error::make_error(
114
0
                                bytes,
115
0
                                nom::error::ErrorKind::Digit,
116
0
                            )))?;
117
                    shift =
118
0
                        shift
119
0
                            .checked_add(16)
120
0
                            .ok_or(nom::Err::Error(nom::error::make_error(
121
0
                                bytes,
122
0
                                nom::error::ErrorKind::Digit,
123
0
                            )))?;
124
                }
125
126
0
                Ok((&[][..], num))
127
0
            },
Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot8json_rpc12payment_info23nom_decode_payment_infopEs0_0B8_
Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot8json_rpc12payment_info23nom_decode_payment_infoINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEEs0_0B8_
128
0
        )),
129
0
        |(weight, class, partial_fee)| methods::RuntimeDispatchInfo {
130
0
            weight,
131
0
            class,
132
0
            partial_fee,
133
0
        },
Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot8json_rpc12payment_info23nom_decode_payment_infopEs1_0B8_
Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot8json_rpc12payment_info23nom_decode_payment_infoINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEEs1_0B8_
134
0
    )
135
0
}
Unexecuted instantiation: _RINvNtNtCsN16ciHI6Qf_7smoldot8json_rpc12payment_info23nom_decode_payment_infopEB6_
Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot8json_rpc12payment_info23nom_decode_payment_infoINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEEB6_