chain: ensure impl Deserialize for Amount validates data.
This uses serde's try_from attribute to run deserialized values through the TryFrom impl. Also adds a test to make sure that validation actually does happen.
This commit is contained in:
parent
238dec51dd
commit
7d0a3debb6
|
|
@ -152,6 +152,16 @@ version = "0.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cdcf67bb7ba7797a081cd19009948ab533af7c355d5caf1d08c777582d351e9c"
|
checksum = "cdcf67bb7ba7797a081cd19009948ab533af7c355d5caf1d08c777582d351e9c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bincode"
|
||||||
|
version = "1.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bit-set"
|
name = "bit-set"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
|
|
@ -2611,6 +2621,7 @@ name = "zebra-chain"
|
||||||
version = "3.0.0-alpha.0"
|
version = "3.0.0-alpha.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bech32",
|
"bech32",
|
||||||
|
"bincode",
|
||||||
"blake2b_simd",
|
"blake2b_simd",
|
||||||
"blake2s_simd",
|
"blake2s_simd",
|
||||||
"bs58",
|
"bs58",
|
||||||
|
|
|
||||||
|
|
@ -37,3 +37,4 @@ proptest = "0.10"
|
||||||
proptest-derive = "0.2.0"
|
proptest-derive = "0.2.0"
|
||||||
zebra-test = { path = "../zebra-test/" }
|
zebra-test = { path = "../zebra-test/" }
|
||||||
color-eyre = "0.5"
|
color-eyre = "0.5"
|
||||||
|
bincode = "1"
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ type Result<T, E = Error> = std::result::Result<T, E>;
|
||||||
|
|
||||||
/// A runtime validated type for representing amounts of zatoshis
|
/// A runtime validated type for representing amounts of zatoshis
|
||||||
#[derive(Debug, Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]
|
#[derive(Debug, Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]
|
||||||
|
#[serde(try_from = "i64")]
|
||||||
|
#[serde(bound = "C: AmountConstraint")]
|
||||||
pub struct Amount<C = NegativeAllowed>(i64, PhantomData<C>);
|
pub struct Amount<C = NegativeAllowed>(i64, PhantomData<C>);
|
||||||
|
|
||||||
impl<C> Amount<C> {
|
impl<C> Amount<C> {
|
||||||
|
|
@ -384,4 +386,27 @@ mod test {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deserialize_checks_bounds() -> Result<()> {
|
||||||
|
let big = MAX_MONEY * 2;
|
||||||
|
let neg = -10;
|
||||||
|
|
||||||
|
let big_bytes = bincode::serialize(&big)?;
|
||||||
|
let neg_bytes = bincode::serialize(&neg)?;
|
||||||
|
|
||||||
|
bincode::deserialize::<Amount<NonNegative>>(&big_bytes)
|
||||||
|
.expect_err("deserialization should reject too large values");
|
||||||
|
bincode::deserialize::<Amount<NegativeAllowed>>(&big_bytes)
|
||||||
|
.expect_err("deserialization should reject too large values");
|
||||||
|
|
||||||
|
bincode::deserialize::<Amount<NonNegative>>(&neg_bytes)
|
||||||
|
.expect_err("NonNegative deserialization should reject negative values");
|
||||||
|
let amount = bincode::deserialize::<Amount<NegativeAllowed>>(&neg_bytes)
|
||||||
|
.expect("NegativeAllowed deserialization should allow negative values");
|
||||||
|
|
||||||
|
assert_eq!(amount.0, neg);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue