Skip to content

Commit 471d2a2

Browse files
committed
feat(json_rpc): accept strings as bigints when parsing raw transactions
1 parent 64c0ed0 commit 471d2a2

File tree

2 files changed

+32
-17
lines changed

2 files changed

+32
-17
lines changed

data_structures/src/chain/mod.rs

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ use std::{
1111

1212
use bech32::{FromBase32, ToBase32};
1313
use bls_signatures_rs::{bn256, bn256::Bn256, MultiSignature};
14+
use core::fmt::Display;
1415
use ethereum_types::U256;
1516
use failure::Fail;
1617
use futures::future::BoxFuture;
1718
use ordered_float::OrderedFloat;
1819
use serde::{Deserialize, Deserializer, Serialize};
19-
use core::fmt::Display;
2020

2121
use partial_struct::PartialStruct;
2222
use witnet_crypto::{
@@ -1605,28 +1605,14 @@ pub struct ValueTransferOutput {
16051605
/// Address that will receive the value
16061606
pub pkh: PublicKeyHash,
16071607
/// Transferred value in nanowits
1608-
#[serde(
1609-
serialize_with = "u64_to_string",
1610-
deserialize_with = "number_from_string"
1611-
)]
1608+
#[serde(deserialize_with = "number_from_string")]
16121609
pub value: u64,
16131610
/// The value attached to a time-locked output cannot be spent before the specified
16141611
/// timestamp. That is, they cannot be used as an input in any transaction of a
16151612
/// subsequent block proposed for an epoch whose opening timestamp predates the time lock.
16161613
pub time_lock: u64,
16171614
}
16181615

1619-
pub fn u64_to_string<S>(val: &u64, serializer: S) -> Result<S::Ok, S::Error>
1620-
where
1621-
S: serde::Serializer,
1622-
{
1623-
if serializer.is_human_readable() {
1624-
serializer.serialize_str(&val.to_string())
1625-
} else {
1626-
serializer.serialize_u64(*val)
1627-
}
1628-
}
1629-
16301616
pub fn number_from_string<'de, T, D>(deserializer: D) -> Result<T, D::Error>
16311617
where
16321618
D: Deserializer<'de>,
@@ -1668,10 +1654,12 @@ pub struct DataRequestOutput {
16681654
/// Data request structure
16691655
pub data_request: RADRequest,
16701656
/// Reward in nanowits that will be earned by honest witnesses
1657+
#[serde(deserialize_with = "number_from_string")]
16711658
pub witness_reward: u64,
16721659
/// Number of witnesses that will resolve this data request
16731660
pub witnesses: u16,
16741661
/// This fee will be earn by the miner when include commits and/or reveals in the block
1662+
#[serde(deserialize_with = "number_from_string")]
16751663
pub commit_and_reveal_fee: u64,
16761664
/// The minimum percentage of non-error reveals required to consider this data request as
16771665
/// "resolved" instead of as "error".
@@ -1683,6 +1671,7 @@ pub struct DataRequestOutput {
16831671
/// this data request.
16841672
/// This field must be >= collateral_minimum, or zero.
16851673
/// If zero, it will be treated as collateral_minimum.
1674+
#[serde(deserialize_with = "number_from_string")]
16861675
pub collateral: u64,
16871676
}
16881677

@@ -1732,6 +1721,7 @@ impl DataRequestOutput {
17321721
pub struct StakeOutput {
17331722
pub authorization: KeyedSignature,
17341723
pub key: StakeKey<PublicKeyHash>,
1724+
#[serde(deserialize_with = "number_from_string")]
17351725
pub value: u64,
17361726
}
17371727

data_structures/src/transaction.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use std::convert::TryFrom;
2+
use std::str::FromStr;
23
use std::sync::{Arc, RwLock};
34

45
use protobuf::Message;
5-
use serde::{Deserialize, Serialize};
6+
use serde::{Deserialize, Deserializer, Serialize};
67

78
use witnet_crypto::{
89
hash::calculate_sha256, merkle::FullMerkleTree, secp256k1::Message as Secp256k1Message,
@@ -863,14 +864,38 @@ impl UnstakeTransaction {
863864
pub struct UnstakeTransactionBody {
864865
pub operator: PublicKeyHash,
865866
pub withdrawal: ValueTransferOutput,
867+
#[serde(deserialize_with = "number_from_string")]
866868
pub fee: u64,
869+
#[serde(deserialize_with = "number_from_string")]
867870
pub nonce: u64,
868871

869872
#[protobuf_convert(skip)]
870873
#[serde(skip)]
871874
hash: MemoHash,
872875
}
873876

877+
pub fn number_from_string<'de, T, D>(deserializer: D) -> Result<T, D::Error>
878+
where
879+
D: Deserializer<'de>,
880+
T: FromStr + serde::Deserialize<'de>,
881+
<T as FromStr>::Err: std::fmt::Display,
882+
{
883+
#[derive(Deserialize)]
884+
#[serde(untagged)]
885+
enum StringOrInt<T> {
886+
String(String),
887+
Number(T),
888+
}
889+
if deserializer.is_human_readable() {
890+
match StringOrInt::<T>::deserialize(deserializer)? {
891+
StringOrInt::String(s) => s.parse::<T>().map_err(serde::de::Error::custom),
892+
StringOrInt::Number(i) => Ok(i),
893+
}
894+
} else {
895+
T::deserialize(deserializer)
896+
}
897+
}
898+
874899
impl UnstakeTransactionBody {
875900
/// Creates a new stake transaction body.
876901
pub fn new(

0 commit comments

Comments
 (0)