mirror of
https://github.com/serai-dex/serai.git
synced 2024-12-22 19:49:22 +00:00
Replace usage of io::Error::new(io::ErrorKind::Other,
with io::Error::other
Newly possible with Rust 1.74.
This commit is contained in:
parent
05b975dff9
commit
797604ad73
25 changed files with 114 additions and 154 deletions
|
@ -91,10 +91,8 @@ impl ReceivedOutput {
|
||||||
pub fn read<R: Read>(r: &mut R) -> io::Result<ReceivedOutput> {
|
pub fn read<R: Read>(r: &mut R) -> io::Result<ReceivedOutput> {
|
||||||
Ok(ReceivedOutput {
|
Ok(ReceivedOutput {
|
||||||
offset: Secp256k1::read_F(r)?,
|
offset: Secp256k1::read_F(r)?,
|
||||||
output: TxOut::consensus_decode(r)
|
output: TxOut::consensus_decode(r).map_err(|_| io::Error::other("invalid TxOut"))?,
|
||||||
.map_err(|_| io::Error::new(io::ErrorKind::Other, "invalid TxOut"))?,
|
outpoint: OutPoint::consensus_decode(r).map_err(|_| io::Error::other("invalid OutPoint"))?,
|
||||||
outpoint: OutPoint::consensus_decode(r)
|
|
||||||
.map_err(|_| io::Error::new(io::ErrorKind::Other, "invalid OutPoint"))?,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -304,7 +304,7 @@ async_sequential! {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the change is correct
|
// Make sure the change is correct
|
||||||
assert_eq!(needed_fee, u64::try_from(tx.weight()).unwrap() * FEE);
|
assert_eq!(needed_fee, u64::from(tx.weight()) * FEE);
|
||||||
let input_value = output.value() + offset_output.value();
|
let input_value = output.value() + offset_output.value();
|
||||||
let output_value = tx.output.iter().map(|output| output.value.to_sat()).sum::<u64>();
|
let output_value = tx.output.iter().map(|output| output.value.to_sat()).sum::<u64>();
|
||||||
assert_eq!(input_value - output_value, needed_fee);
|
assert_eq!(input_value - output_value, needed_fee);
|
||||||
|
|
|
@ -141,7 +141,7 @@ impl Protocol {
|
||||||
0 => match read_byte(r)? {
|
0 => match read_byte(r)? {
|
||||||
14 => Protocol::v14,
|
14 => Protocol::v14,
|
||||||
16 => Protocol::v16,
|
16 => Protocol::v16,
|
||||||
_ => Err(io::Error::new(io::ErrorKind::Other, "unrecognized monero protocol"))?,
|
_ => Err(io::Error::other("unrecognized monero protocol"))?,
|
||||||
},
|
},
|
||||||
// Custom
|
// Custom
|
||||||
1 => match read_byte(r)? {
|
1 => match read_byte(r)? {
|
||||||
|
@ -150,26 +150,24 @@ impl Protocol {
|
||||||
bp_plus: match read_byte(r)? {
|
bp_plus: match read_byte(r)? {
|
||||||
0 => false,
|
0 => false,
|
||||||
1 => true,
|
1 => true,
|
||||||
_ => Err(io::Error::new(io::ErrorKind::Other, "invalid bool serialization"))?,
|
_ => Err(io::Error::other("invalid bool serialization"))?,
|
||||||
},
|
},
|
||||||
optimal_rct_type: RctType::from_byte(read_byte(r)?)
|
optimal_rct_type: RctType::from_byte(read_byte(r)?)
|
||||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid RctType serialization"))?,
|
.ok_or_else(|| io::Error::other("invalid RctType serialization"))?,
|
||||||
view_tags: match read_byte(r)? {
|
view_tags: match read_byte(r)? {
|
||||||
0 => false,
|
0 => false,
|
||||||
1 => true,
|
1 => true,
|
||||||
_ => Err(io::Error::new(io::ErrorKind::Other, "invalid bool serialization"))?,
|
_ => Err(io::Error::other("invalid bool serialization"))?,
|
||||||
},
|
},
|
||||||
v16_fee: match read_byte(r)? {
|
v16_fee: match read_byte(r)? {
|
||||||
0 => false,
|
0 => false,
|
||||||
1 => true,
|
1 => true,
|
||||||
_ => Err(io::Error::new(io::ErrorKind::Other, "invalid bool serialization"))?,
|
_ => Err(io::Error::other("invalid bool serialization"))?,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
_ => {
|
_ => Err(io::Error::other("unrecognized custom protocol serialization"))?,
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "unrecognized custom protocol serialization"))?
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_ => Err(io::Error::new(io::ErrorKind::Other, "unrecognized protocol serialization"))?,
|
_ => Err(io::Error::other("unrecognized protocol serialization"))?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,10 +184,10 @@ impl Algorithm<Ed25519> for ClsagMultisig {
|
||||||
reader.read_exact(&mut bytes)?;
|
reader.read_exact(&mut bytes)?;
|
||||||
// dfg ensures the point is torsion free
|
// dfg ensures the point is torsion free
|
||||||
let xH = Option::<dfg::EdwardsPoint>::from(dfg::EdwardsPoint::from_bytes(&bytes))
|
let xH = Option::<dfg::EdwardsPoint>::from(dfg::EdwardsPoint::from_bytes(&bytes))
|
||||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid key image"))?;
|
.ok_or_else(|| io::Error::other("invalid key image"))?;
|
||||||
// Ensure this is a canonical point
|
// Ensure this is a canonical point
|
||||||
if xH.to_bytes() != bytes {
|
if xH.to_bytes() != bytes {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "non-canonical key image"))?;
|
Err(io::Error::other("non-canonical key image"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ClsagAddendum { key_image: xH, dleq: DLEqProof::<dfg::EdwardsPoint>::read(reader)? })
|
Ok(ClsagAddendum { key_image: xH, dleq: DLEqProof::<dfg::EdwardsPoint>::read(reader)? })
|
||||||
|
|
|
@ -147,8 +147,8 @@ impl RctBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read<R: Read>(inputs: usize, outputs: usize, r: &mut R) -> io::Result<(RctBase, RctType)> {
|
pub fn read<R: Read>(inputs: usize, outputs: usize, r: &mut R) -> io::Result<(RctBase, RctType)> {
|
||||||
let rct_type = RctType::from_byte(read_byte(r)?)
|
let rct_type =
|
||||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid RCT type"))?;
|
RctType::from_byte(read_byte(r)?).ok_or_else(|| io::Error::other("invalid RCT type"))?;
|
||||||
|
|
||||||
match rct_type {
|
match rct_type {
|
||||||
RctType::Null => {}
|
RctType::Null => {}
|
||||||
|
@ -164,7 +164,7 @@ impl RctBase {
|
||||||
// If there are Bulletproofs, there must be a matching amount of outputs, implicitly
|
// If there are Bulletproofs, there must be a matching amount of outputs, implicitly
|
||||||
// banning 0 outputs
|
// banning 0 outputs
|
||||||
// Since HF 12 (CLSAG being 13), a 2-output minimum has also been enforced
|
// Since HF 12 (CLSAG being 13), a 2-output minimum has also been enforced
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "RCT with Bulletproofs(+) had 0 outputs"))?;
|
Err(io::Error::other("RCT with Bulletproofs(+) had 0 outputs"))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,7 +273,7 @@ impl RctPrunable {
|
||||||
// And then for RctNull, that's only allowed for miner TXs which require one input of
|
// And then for RctNull, that's only allowed for miner TXs which require one input of
|
||||||
// Input::Gen
|
// Input::Gen
|
||||||
if decoys.is_empty() {
|
if decoys.is_empty() {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "transaction had no inputs"))?;
|
Err(io::Error::other("transaction had no inputs"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(match rct_type {
|
Ok(match rct_type {
|
||||||
|
@ -295,7 +295,7 @@ impl RctPrunable {
|
||||||
read_varint(r)?
|
read_varint(r)?
|
||||||
}) != 1
|
}) != 1
|
||||||
{
|
{
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "n bulletproofs instead of one"))?;
|
Err(io::Error::other("n bulletproofs instead of one"))?;
|
||||||
}
|
}
|
||||||
Bulletproofs::read(r)?
|
Bulletproofs::read(r)?
|
||||||
},
|
},
|
||||||
|
@ -306,7 +306,7 @@ impl RctPrunable {
|
||||||
RctType::Clsag | RctType::BulletproofsPlus => RctPrunable::Clsag {
|
RctType::Clsag | RctType::BulletproofsPlus => RctPrunable::Clsag {
|
||||||
bulletproofs: {
|
bulletproofs: {
|
||||||
if read_varint::<_, u64>(r)? != 1 {
|
if read_varint::<_, u64>(r)? != 1 {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "n bulletproofs instead of one"))?;
|
Err(io::Error::other("n bulletproofs instead of one"))?;
|
||||||
}
|
}
|
||||||
(if rct_type == RctType::Clsag { Bulletproofs::read } else { Bulletproofs::read_plus })(
|
(if rct_type == RctType::Clsag { Bulletproofs::read } else { Bulletproofs::read_plus })(
|
||||||
r,
|
r,
|
||||||
|
|
|
@ -385,7 +385,7 @@ impl<R: RpcConnection> Rpc<R> {
|
||||||
let mut is_okay = false;
|
let mut is_okay = false;
|
||||||
|
|
||||||
if read_bytes::<_, { EPEE_HEADER.len() }>(&mut indexes)? != EPEE_HEADER {
|
if read_bytes::<_, { EPEE_HEADER.len() }>(&mut indexes)? != EPEE_HEADER {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "invalid header"))?;
|
Err(io::Error::other("invalid header"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let read_object = |reader: &mut &[u8]| -> io::Result<Vec<u64>> {
|
let read_object = |reader: &mut &[u8]| -> io::Result<Vec<u64>> {
|
||||||
|
@ -401,7 +401,7 @@ impl<R: RpcConnection> Rpc<R> {
|
||||||
let iters = if type_with_array_flag != kind { read_epee_vi(reader)? } else { 1 };
|
let iters = if type_with_array_flag != kind { read_epee_vi(reader)? } else { 1 };
|
||||||
|
|
||||||
if (&name == b"o_indexes") && (kind != 5) {
|
if (&name == b"o_indexes") && (kind != 5) {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "o_indexes weren't u64s"))?;
|
Err(io::Error::other("o_indexes weren't u64s"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let f = match kind {
|
let f = match kind {
|
||||||
|
@ -428,28 +428,19 @@ impl<R: RpcConnection> Rpc<R> {
|
||||||
let len = read_epee_vi(reader)?;
|
let len = read_epee_vi(reader)?;
|
||||||
read_raw_vec(
|
read_raw_vec(
|
||||||
read_byte,
|
read_byte,
|
||||||
len
|
len.try_into().map_err(|_| io::Error::other("u64 length exceeded usize"))?,
|
||||||
.try_into()
|
|
||||||
.map_err(|_| io::Error::new(io::ErrorKind::Other, "u64 length exceeded usize"))?,
|
|
||||||
reader,
|
reader,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
// bool
|
// bool
|
||||||
11 => |reader: &mut &[u8]| read_raw_vec(read_byte, 1, reader),
|
11 => |reader: &mut &[u8]| read_raw_vec(read_byte, 1, reader),
|
||||||
// object, errors here as it shouldn't be used on this call
|
// object, errors here as it shouldn't be used on this call
|
||||||
12 => |_: &mut &[u8]| {
|
12 => {
|
||||||
Err(io::Error::new(
|
|_: &mut &[u8]| Err(io::Error::other("node used object in reply to get_o_indexes"))
|
||||||
io::ErrorKind::Other,
|
|
||||||
"node used object in reply to get_o_indexes",
|
|
||||||
))
|
|
||||||
},
|
|
||||||
// array, so far unused
|
|
||||||
13 => |_: &mut &[u8]| {
|
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "node used the unused array type"))
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
|_: &mut &[u8]| Err(io::Error::new(io::ErrorKind::Other, "node used an invalid type"))
|
|
||||||
}
|
}
|
||||||
|
// array, so far unused
|
||||||
|
13 => |_: &mut &[u8]| Err(io::Error::other("node used the unused array type")),
|
||||||
|
_ => |_: &mut &[u8]| Err(io::Error::other("node used an invalid type")),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut bytes_res = vec![];
|
let mut bytes_res = vec![];
|
||||||
|
@ -461,21 +452,23 @@ impl<R: RpcConnection> Rpc<R> {
|
||||||
match name.as_slice() {
|
match name.as_slice() {
|
||||||
b"o_indexes" => {
|
b"o_indexes" => {
|
||||||
for o_index in bytes_res {
|
for o_index in bytes_res {
|
||||||
actual_res.push(u64::from_le_bytes(o_index.try_into().map_err(|_| {
|
actual_res.push(u64::from_le_bytes(
|
||||||
io::Error::new(io::ErrorKind::Other, "node didn't provide 8 bytes for a u64")
|
o_index
|
||||||
})?));
|
.try_into()
|
||||||
|
.map_err(|_| io::Error::other("node didn't provide 8 bytes for a u64"))?,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
res = Some(actual_res);
|
res = Some(actual_res);
|
||||||
}
|
}
|
||||||
b"status" => {
|
b"status" => {
|
||||||
if bytes_res
|
if bytes_res
|
||||||
.first()
|
.first()
|
||||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "status wasn't a string"))?
|
.ok_or_else(|| io::Error::other("status wasn't a string"))?
|
||||||
.as_slice() !=
|
.as_slice() !=
|
||||||
b"OK"
|
b"OK"
|
||||||
{
|
{
|
||||||
// TODO: Better handle non-OK responses
|
// TODO: Better handle non-OK responses
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "response wasn't OK"))?;
|
Err(io::Error::other("response wasn't OK"))?;
|
||||||
}
|
}
|
||||||
is_okay = true;
|
is_okay = true;
|
||||||
}
|
}
|
||||||
|
@ -490,7 +483,7 @@ impl<R: RpcConnection> Rpc<R> {
|
||||||
// Didn't return a response with a status
|
// Didn't return a response with a status
|
||||||
// (if the status wasn't okay, we would've already errored)
|
// (if the status wasn't okay, we would've already errored)
|
||||||
if !is_okay {
|
if !is_okay {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "response didn't contain a status"))?;
|
Err(io::Error::other("response didn't contain a status"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the Vec was empty, it would've been omitted, hence the unwrap_or
|
// If the Vec was empty, it would've been omitted, hence the unwrap_or
|
||||||
|
|
|
@ -100,19 +100,17 @@ pub(crate) fn read_varint<R: Read, U: sealed::VarInt>(r: &mut R) -> io::Result<U
|
||||||
while {
|
while {
|
||||||
let b = read_byte(r)?;
|
let b = read_byte(r)?;
|
||||||
if (bits != 0) && (b == 0) {
|
if (bits != 0) && (b == 0) {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "non-canonical varint"))?;
|
Err(io::Error::other("non-canonical varint"))?;
|
||||||
}
|
}
|
||||||
if ((bits + 7) > 64) && (b >= (1 << (64 - bits))) {
|
if ((bits + 7) > 64) && (b >= (1 << (64 - bits))) {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "varint overflow"))?;
|
Err(io::Error::other("varint overflow"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
res += u64::from(b & (!VARINT_CONTINUATION_MASK)) << bits;
|
res += u64::from(b & (!VARINT_CONTINUATION_MASK)) << bits;
|
||||||
bits += 7;
|
bits += 7;
|
||||||
b & VARINT_CONTINUATION_MASK == VARINT_CONTINUATION_MASK
|
b & VARINT_CONTINUATION_MASK == VARINT_CONTINUATION_MASK
|
||||||
} {}
|
} {}
|
||||||
res
|
res.try_into().map_err(|_| io::Error::other("VarInt does not fit into integer type"))
|
||||||
.try_into()
|
|
||||||
.map_err(|_| io::Error::new(io::ErrorKind::Other, "VarInt does not fit into integer type"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// All scalar fields supported by monero-serai are checked to be canonical for valid transactions
|
// All scalar fields supported by monero-serai are checked to be canonical for valid transactions
|
||||||
|
@ -123,7 +121,7 @@ pub(crate) fn read_varint<R: Read, U: sealed::VarInt>(r: &mut R) -> io::Result<U
|
||||||
// reduction applied
|
// reduction applied
|
||||||
pub(crate) fn read_scalar<R: Read>(r: &mut R) -> io::Result<Scalar> {
|
pub(crate) fn read_scalar<R: Read>(r: &mut R) -> io::Result<Scalar> {
|
||||||
Option::from(Scalar::from_canonical_bytes(read_bytes(r)?))
|
Option::from(Scalar::from_canonical_bytes(read_bytes(r)?))
|
||||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "unreduced scalar"))
|
.ok_or_else(|| io::Error::other("unreduced scalar"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn read_point<R: Read>(r: &mut R) -> io::Result<EdwardsPoint> {
|
pub(crate) fn read_point<R: Read>(r: &mut R) -> io::Result<EdwardsPoint> {
|
||||||
|
@ -132,14 +130,14 @@ pub(crate) fn read_point<R: Read>(r: &mut R) -> io::Result<EdwardsPoint> {
|
||||||
.decompress()
|
.decompress()
|
||||||
// Ban points which are either unreduced or -0
|
// Ban points which are either unreduced or -0
|
||||||
.filter(|point| point.compress().to_bytes() == bytes)
|
.filter(|point| point.compress().to_bytes() == bytes)
|
||||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid point"))
|
.ok_or_else(|| io::Error::other("invalid point"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn read_torsion_free_point<R: Read>(r: &mut R) -> io::Result<EdwardsPoint> {
|
pub(crate) fn read_torsion_free_point<R: Read>(r: &mut R) -> io::Result<EdwardsPoint> {
|
||||||
read_point(r)
|
read_point(r)
|
||||||
.ok()
|
.ok()
|
||||||
.filter(EdwardsPoint::is_torsion_free)
|
.filter(EdwardsPoint::is_torsion_free)
|
||||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid point"))
|
.ok_or_else(|| io::Error::other("invalid point"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn read_raw_vec<R: Read, T, F: Fn(&mut R) -> io::Result<T>>(
|
pub(crate) fn read_raw_vec<R: Read, T, F: Fn(&mut R) -> io::Result<T>>(
|
||||||
|
|
|
@ -67,9 +67,7 @@ impl Input {
|
||||||
key_image: read_torsion_free_point(r)?,
|
key_image: read_torsion_free_point(r)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => Err(io::Error::other("Tried to deserialize unknown/unused input type"))?,
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "Tried to deserialize unknown/unused input type"))?
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +107,7 @@ impl Output {
|
||||||
let amount = read_varint(r)?;
|
let amount = read_varint(r)?;
|
||||||
let amount = if rct {
|
let amount = if rct {
|
||||||
if amount != 0 {
|
if amount != 0 {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "RCT TX output wasn't 0"))?;
|
Err(io::Error::other("RCT TX output wasn't 0"))?;
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
@ -119,10 +117,7 @@ impl Output {
|
||||||
let view_tag = match read_byte(r)? {
|
let view_tag = match read_byte(r)? {
|
||||||
2 => false,
|
2 => false,
|
||||||
3 => true,
|
3 => true,
|
||||||
_ => Err(io::Error::new(
|
_ => Err(io::Error::other("Tried to deserialize unknown/unused output type"))?,
|
||||||
io::ErrorKind::Other,
|
|
||||||
"Tried to deserialize unknown/unused output type",
|
|
||||||
))?,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Output {
|
Ok(Output {
|
||||||
|
@ -220,14 +215,14 @@ impl TransactionPrefix {
|
||||||
let version = read_varint(r)?;
|
let version = read_varint(r)?;
|
||||||
// TODO: Create an enum out of version
|
// TODO: Create an enum out of version
|
||||||
if (version == 0) || (version > 2) {
|
if (version == 0) || (version > 2) {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "unrecognized transaction version"))?;
|
Err(io::Error::other("unrecognized transaction version"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let timelock = Timelock::from_raw(read_varint(r)?);
|
let timelock = Timelock::from_raw(read_varint(r)?);
|
||||||
|
|
||||||
let inputs = read_vec(|r| Input::read(r), r)?;
|
let inputs = read_vec(|r| Input::read(r), r)?;
|
||||||
if inputs.is_empty() {
|
if inputs.is_empty() {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "transaction had no inputs"))?;
|
Err(io::Error::other("transaction had no inputs"))?;
|
||||||
}
|
}
|
||||||
let is_miner_tx = matches!(inputs[0], Input::Gen { .. });
|
let is_miner_tx = matches!(inputs[0], Input::Gen { .. });
|
||||||
|
|
||||||
|
@ -310,9 +305,7 @@ impl Transaction {
|
||||||
.inputs
|
.inputs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|input| match input {
|
.map(|input| match input {
|
||||||
Input::Gen(..) => {
|
Input::Gen(..) => Err(io::Error::other("Input::Gen present in non-coinbase v1 TX"))?,
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "Input::Gen present in non-coinbase v1 TX"))?
|
|
||||||
}
|
|
||||||
// v1 TXs can burn v2 outputs
|
// v1 TXs can burn v2 outputs
|
||||||
// dcff3fe4f914d6b6bd4a5b800cc4cca8f2fdd1bd73352f0700d463d36812f328 is one such TX
|
// dcff3fe4f914d6b6bd4a5b800cc4cca8f2fdd1bd73352f0700d463d36812f328 is one such TX
|
||||||
// It includes a pre-RCT signature for a RCT output, yet if you interpret the RCT
|
// It includes a pre-RCT signature for a RCT output, yet if you interpret the RCT
|
||||||
|
@ -326,16 +319,13 @@ impl Transaction {
|
||||||
let mut out = 0;
|
let mut out = 0;
|
||||||
for output in &prefix.outputs {
|
for output in &prefix.outputs {
|
||||||
if output.amount.is_none() {
|
if output.amount.is_none() {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "v1 transaction had a 0-amount output"))?;
|
Err(io::Error::other("v1 transaction had a 0-amount output"))?;
|
||||||
}
|
}
|
||||||
out += output.amount.unwrap();
|
out += output.amount.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
if in_amount < out {
|
if in_amount < out {
|
||||||
Err(io::Error::new(
|
Err(io::Error::other("transaction spent more than it had as inputs"))?;
|
||||||
io::ErrorKind::Other,
|
|
||||||
"transaction spent more than it had as inputs",
|
|
||||||
))?;
|
|
||||||
}
|
}
|
||||||
rct_signatures.base.fee = in_amount - out;
|
rct_signatures.base.fee = in_amount - out;
|
||||||
}
|
}
|
||||||
|
@ -353,7 +343,7 @@ impl Transaction {
|
||||||
r,
|
r,
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "Tried to deserialize unknown version"))?;
|
Err(io::Error::other("Tried to deserialize unknown version"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Transaction { prefix, signatures, rct_signatures })
|
Ok(Transaction { prefix, signatures, rct_signatures })
|
||||||
|
|
|
@ -62,7 +62,7 @@ impl PaymentId {
|
||||||
Ok(match read_byte(r)? {
|
Ok(match read_byte(r)? {
|
||||||
0 => PaymentId::Unencrypted(read_bytes(r)?),
|
0 => PaymentId::Unencrypted(read_bytes(r)?),
|
||||||
1 => PaymentId::Encrypted(read_bytes(r)?),
|
1 => PaymentId::Encrypted(read_bytes(r)?),
|
||||||
_ => Err(io::Error::new(io::ErrorKind::Other, "unknown payment ID type"))?,
|
_ => Err(io::Error::other("unknown payment ID type"))?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,13 +106,13 @@ impl ExtraField {
|
||||||
2 => ExtraField::Nonce({
|
2 => ExtraField::Nonce({
|
||||||
let nonce = read_vec(read_byte, r)?;
|
let nonce = read_vec(read_byte, r)?;
|
||||||
if nonce.len() > MAX_TX_EXTRA_NONCE_SIZE {
|
if nonce.len() > MAX_TX_EXTRA_NONCE_SIZE {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "too long nonce"))?;
|
Err(io::Error::other("too long nonce"))?;
|
||||||
}
|
}
|
||||||
nonce
|
nonce
|
||||||
}),
|
}),
|
||||||
3 => ExtraField::MergeMining(read_varint(r)?, read_bytes(r)?),
|
3 => ExtraField::MergeMining(read_varint(r)?, read_bytes(r)?),
|
||||||
4 => ExtraField::PublicKeys(read_vec(read_point, r)?),
|
4 => ExtraField::PublicKeys(read_vec(read_point, r)?),
|
||||||
_ => Err(io::Error::new(io::ErrorKind::Other, "unknown extra field"))?,
|
_ => Err(io::Error::other("unknown extra field"))?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,7 +146,7 @@ impl Metadata {
|
||||||
let subaddress = if read_byte(r)? == 1 {
|
let subaddress = if read_byte(r)? == 1 {
|
||||||
Some(
|
Some(
|
||||||
SubaddressIndex::new(read_u32(r)?, read_u32(r)?)
|
SubaddressIndex::new(read_u32(r)?, read_u32(r)?)
|
||||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid subaddress in metadata"))?,
|
.ok_or_else(|| io::Error::other("invalid subaddress in metadata"))?,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -965,7 +965,7 @@ impl Eventuality {
|
||||||
String::from_utf8(read_vec(read_byte, r)?)
|
String::from_utf8(read_vec(read_byte, r)?)
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|str| MoneroAddress::from_str_raw(&str).ok())
|
.and_then(|str| MoneroAddress::from_str_raw(&str).ok())
|
||||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid address"))
|
.ok_or_else(|| io::Error::other("invalid address"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_payment<R: io::Read>(r: &mut R) -> io::Result<InternalPayment> {
|
fn read_payment<R: io::Read>(r: &mut R) -> io::Result<InternalPayment> {
|
||||||
|
@ -977,12 +977,12 @@ impl Eventuality {
|
||||||
view: match read_byte(r)? {
|
view: match read_byte(r)? {
|
||||||
0 => None,
|
0 => None,
|
||||||
1 => Some(Zeroizing::new(read_scalar(r)?)),
|
1 => Some(Zeroizing::new(read_scalar(r)?)),
|
||||||
_ => Err(io::Error::new(io::ErrorKind::Other, "invalid change payment"))?,
|
_ => Err(io::Error::other("invalid change payment"))?,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
read_u64(r)?,
|
read_u64(r)?,
|
||||||
),
|
),
|
||||||
_ => Err(io::Error::new(io::ErrorKind::Other, "invalid payment"))?,
|
_ => Err(io::Error::other("invalid payment"))?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,10 @@ mod shims {
|
||||||
Error { kind, error: Box::new(error) }
|
Error { kind, error: Box::new(error) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn other<E: 'static + Send + Sync>(error: E) -> Error {
|
||||||
|
Error { kind: ErrorKind::Other, error: Box::new(error) }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn kind(&self) -> ErrorKind {
|
pub fn kind(&self) -> ErrorKind {
|
||||||
self.kind
|
self.kind
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,8 +151,8 @@ impl TributarySpec {
|
||||||
|
|
||||||
let mut network = [0; 1];
|
let mut network = [0; 1];
|
||||||
reader.read_exact(&mut network)?;
|
reader.read_exact(&mut network)?;
|
||||||
let network = NetworkId::decode(&mut &network[..])
|
let network =
|
||||||
.map_err(|_| io::Error::new(io::ErrorKind::Other, "invalid network"))?;
|
NetworkId::decode(&mut &network[..]).map_err(|_| io::Error::other("invalid network"))?;
|
||||||
|
|
||||||
let mut validators_len = [0; 4];
|
let mut validators_len = [0; 4];
|
||||||
reader.read_exact(&mut validators_len)?;
|
reader.read_exact(&mut validators_len)?;
|
||||||
|
@ -194,7 +194,7 @@ impl<Id: Clone + PartialEq + Eq + Debug + Encode + Decode> Debug for SignData<Id
|
||||||
impl<Id: Clone + PartialEq + Eq + Debug + Encode + Decode> ReadWrite for SignData<Id> {
|
impl<Id: Clone + PartialEq + Eq + Debug + Encode + Decode> ReadWrite for SignData<Id> {
|
||||||
fn read<R: io::Read>(reader: &mut R) -> io::Result<Self> {
|
fn read<R: io::Read>(reader: &mut R) -> io::Result<Self> {
|
||||||
let plan = Id::decode(&mut scale::IoReader(&mut *reader))
|
let plan = Id::decode(&mut scale::IoReader(&mut *reader))
|
||||||
.map_err(|_| io::Error::new(io::ErrorKind::Other, "invalid plan in SignData"))?;
|
.map_err(|_| io::Error::other("invalid plan in SignData"))?;
|
||||||
|
|
||||||
let mut attempt = [0; 4];
|
let mut attempt = [0; 4];
|
||||||
reader.read_exact(&mut attempt)?;
|
reader.read_exact(&mut attempt)?;
|
||||||
|
@ -204,7 +204,7 @@ impl<Id: Clone + PartialEq + Eq + Debug + Encode + Decode> ReadWrite for SignDat
|
||||||
let mut data_pieces = [0];
|
let mut data_pieces = [0];
|
||||||
reader.read_exact(&mut data_pieces)?;
|
reader.read_exact(&mut data_pieces)?;
|
||||||
if data_pieces[0] == 0 {
|
if data_pieces[0] == 0 {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "zero pieces of data in SignData"))?;
|
Err(io::Error::other("zero pieces of data in SignData"))?;
|
||||||
}
|
}
|
||||||
let mut all_data = vec![];
|
let mut all_data = vec![];
|
||||||
for _ in 0 .. data_pieces[0] {
|
for _ in 0 .. data_pieces[0] {
|
||||||
|
@ -236,7 +236,7 @@ impl<Id: Clone + PartialEq + Eq + Debug + Encode + Decode> ReadWrite for SignDat
|
||||||
// Monero is limited to ~120 inputs per TX
|
// Monero is limited to ~120 inputs per TX
|
||||||
//
|
//
|
||||||
// Bitcoin has a much higher input count of 520, yet it only uses 64 bytes per preprocess
|
// Bitcoin has a much higher input count of 520, yet it only uses 64 bytes per preprocess
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "signing data exceeded 65535 bytes"))?;
|
Err(io::Error::other("signing data exceeded 65535 bytes"))?;
|
||||||
}
|
}
|
||||||
writer.write_all(&u16::try_from(data.len()).unwrap().to_le_bytes())?;
|
writer.write_all(&u16::try_from(data.len()).unwrap().to_le_bytes())?;
|
||||||
writer.write_all(data)?;
|
writer.write_all(data)?;
|
||||||
|
@ -370,9 +370,8 @@ impl ReadWrite for Transaction {
|
||||||
0 => Ok(Transaction::RemoveParticipant({
|
0 => Ok(Transaction::RemoveParticipant({
|
||||||
let mut participant = [0; 2];
|
let mut participant = [0; 2];
|
||||||
reader.read_exact(&mut participant)?;
|
reader.read_exact(&mut participant)?;
|
||||||
Participant::new(u16::from_le_bytes(participant)).ok_or_else(|| {
|
Participant::new(u16::from_le_bytes(participant))
|
||||||
io::Error::new(io::ErrorKind::Other, "invalid participant in RemoveParticipant")
|
.ok_or_else(|| io::Error::other("invalid participant in RemoveParticipant"))?
|
||||||
})?
|
|
||||||
})),
|
})),
|
||||||
|
|
||||||
1 => {
|
1 => {
|
||||||
|
@ -385,15 +384,14 @@ impl ReadWrite for Transaction {
|
||||||
reader.read_exact(&mut commitments_len)?;
|
reader.read_exact(&mut commitments_len)?;
|
||||||
let commitments_len = usize::from(commitments_len[0]);
|
let commitments_len = usize::from(commitments_len[0]);
|
||||||
if commitments_len == 0 {
|
if commitments_len == 0 {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "zero commitments in DkgCommitments"))?;
|
Err(io::Error::other("zero commitments in DkgCommitments"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut each_commitments_len = [0; 2];
|
let mut each_commitments_len = [0; 2];
|
||||||
reader.read_exact(&mut each_commitments_len)?;
|
reader.read_exact(&mut each_commitments_len)?;
|
||||||
let each_commitments_len = usize::from(u16::from_le_bytes(each_commitments_len));
|
let each_commitments_len = usize::from(u16::from_le_bytes(each_commitments_len));
|
||||||
if (commitments_len * each_commitments_len) > TRANSACTION_SIZE_LIMIT {
|
if (commitments_len * each_commitments_len) > TRANSACTION_SIZE_LIMIT {
|
||||||
Err(io::Error::new(
|
Err(io::Error::other(
|
||||||
io::ErrorKind::Other,
|
|
||||||
"commitments present in transaction exceeded transaction size limit",
|
"commitments present in transaction exceeded transaction size limit",
|
||||||
))?;
|
))?;
|
||||||
}
|
}
|
||||||
|
@ -454,15 +452,13 @@ impl ReadWrite for Transaction {
|
||||||
|
|
||||||
let mut accuser = [0; 2];
|
let mut accuser = [0; 2];
|
||||||
reader.read_exact(&mut accuser)?;
|
reader.read_exact(&mut accuser)?;
|
||||||
let accuser = Participant::new(u16::from_le_bytes(accuser)).ok_or_else(|| {
|
let accuser = Participant::new(u16::from_le_bytes(accuser))
|
||||||
io::Error::new(io::ErrorKind::Other, "invalid participant in InvalidDkgShare")
|
.ok_or_else(|| io::Error::other("invalid participant in InvalidDkgShare"))?;
|
||||||
})?;
|
|
||||||
|
|
||||||
let mut faulty = [0; 2];
|
let mut faulty = [0; 2];
|
||||||
reader.read_exact(&mut faulty)?;
|
reader.read_exact(&mut faulty)?;
|
||||||
let faulty = Participant::new(u16::from_le_bytes(faulty)).ok_or_else(|| {
|
let faulty = Participant::new(u16::from_le_bytes(faulty))
|
||||||
io::Error::new(io::ErrorKind::Other, "invalid participant in InvalidDkgShare")
|
.ok_or_else(|| io::Error::other("invalid participant in InvalidDkgShare"))?;
|
||||||
})?;
|
|
||||||
|
|
||||||
let mut blame_len = [0; 2];
|
let mut blame_len = [0; 2];
|
||||||
reader.read_exact(&mut blame_len)?;
|
reader.read_exact(&mut blame_len)?;
|
||||||
|
@ -534,7 +530,7 @@ impl ReadWrite for Transaction {
|
||||||
Ok(Transaction::SignCompleted { plan, tx_hash, first_signer, signature })
|
Ok(Transaction::SignCompleted { plan, tx_hash, first_signer, signature })
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => Err(io::Error::new(io::ErrorKind::Other, "invalid transaction type")),
|
_ => Err(io::Error::other("invalid transaction type")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,15 +545,12 @@ impl ReadWrite for Transaction {
|
||||||
writer.write_all(&[1])?;
|
writer.write_all(&[1])?;
|
||||||
writer.write_all(&attempt.to_le_bytes())?;
|
writer.write_all(&attempt.to_le_bytes())?;
|
||||||
if commitments.is_empty() {
|
if commitments.is_empty() {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "zero commitments in DkgCommitments"))?
|
Err(io::Error::other("zero commitments in DkgCommitments"))?
|
||||||
}
|
}
|
||||||
writer.write_all(&[u8::try_from(commitments.len()).unwrap()])?;
|
writer.write_all(&[u8::try_from(commitments.len()).unwrap()])?;
|
||||||
for commitments_i in commitments {
|
for commitments_i in commitments {
|
||||||
if commitments_i.len() != commitments[0].len() {
|
if commitments_i.len() != commitments[0].len() {
|
||||||
Err(io::Error::new(
|
Err(io::Error::other("commitments of differing sizes in DkgCommitments"))?
|
||||||
io::ErrorKind::Other,
|
|
||||||
"commitments of differing sizes in DkgCommitments",
|
|
||||||
))?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writer.write_all(&u16::try_from(commitments[0].len()).unwrap().to_le_bytes())?;
|
writer.write_all(&u16::try_from(commitments[0].len()).unwrap().to_le_bytes())?;
|
||||||
|
|
|
@ -81,7 +81,7 @@ impl<T: TransactionTrait> ReadWrite for Transaction<T> {
|
||||||
let tx = T::read(reader)?;
|
let tx = T::read(reader)?;
|
||||||
Ok(Transaction::Application(tx))
|
Ok(Transaction::Application(tx))
|
||||||
}
|
}
|
||||||
_ => Err(io::Error::new(io::ErrorKind::Other, "invalid transaction type")),
|
_ => Err(io::Error::other("invalid transaction type")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
|
fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
|
||||||
|
|
|
@ -412,7 +412,7 @@ async fn block_tx_ordering() {
|
||||||
match kind[0] {
|
match kind[0] {
|
||||||
0 => Ok(SignedTx::Signed(Box::new(SignedTransaction::read(reader)?))),
|
0 => Ok(SignedTx::Signed(Box::new(SignedTransaction::read(reader)?))),
|
||||||
1 => Ok(SignedTx::Provided(Box::new(ProvidedTransaction::read(reader)?))),
|
1 => Ok(SignedTx::Provided(Box::new(ProvidedTransaction::read(reader)?))),
|
||||||
_ => Err(io::Error::new(io::ErrorKind::Other, "invalid transaction type")),
|
_ => Err(io::Error::other("invalid transaction type")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ impl ReadWrite for Signed {
|
||||||
reader.read_exact(&mut nonce)?;
|
reader.read_exact(&mut nonce)?;
|
||||||
let nonce = u32::from_le_bytes(nonce);
|
let nonce = u32::from_le_bytes(nonce);
|
||||||
if nonce >= (u32::MAX - 1) {
|
if nonce >= (u32::MAX - 1) {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "nonce exceeded limit"))?;
|
Err(io::Error::other("nonce exceeded limit"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut signature = SchnorrSignature::<Ristretto>::read(reader)?;
|
let mut signature = SchnorrSignature::<Ristretto>::read(reader)?;
|
||||||
|
@ -64,7 +64,7 @@ impl ReadWrite for Signed {
|
||||||
// We should never produce zero signatures though meaning this should never come up
|
// We should never produce zero signatures though meaning this should never come up
|
||||||
// If it does somehow come up, this is a decent courtesy
|
// If it does somehow come up, this is a decent courtesy
|
||||||
signature.zeroize();
|
signature.zeroize();
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "signature nonce was identity"))?;
|
Err(io::Error::other("signature nonce was identity"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Signed { signer, nonce, signature })
|
Ok(Signed { signer, nonce, signature })
|
||||||
|
@ -73,7 +73,7 @@ impl ReadWrite for Signed {
|
||||||
fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
|
fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
|
||||||
// This is either an invalid signature or a private key leak
|
// This is either an invalid signature or a private key leak
|
||||||
if self.signature.R.is_identity().into() {
|
if self.signature.R.is_identity().into() {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "signature nonce was identity"))?;
|
Err(io::Error::other("signature nonce was identity"))?;
|
||||||
}
|
}
|
||||||
writer.write_all(&self.signer.to_bytes())?;
|
writer.write_all(&self.signer.to_bytes())?;
|
||||||
writer.write_all(&self.nonce.to_le_bytes())?;
|
writer.write_all(&self.nonce.to_le_bytes())?;
|
||||||
|
|
|
@ -93,7 +93,7 @@ pub trait Ciphersuite:
|
||||||
|
|
||||||
// ff mandates this is canonical
|
// ff mandates this is canonical
|
||||||
let res = Option::<Self::F>::from(Self::F::from_repr(encoding))
|
let res = Option::<Self::F>::from(Self::F::from_repr(encoding))
|
||||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "non-canonical scalar"));
|
.ok_or_else(|| io::Error::other("non-canonical scalar"));
|
||||||
encoding.as_mut().zeroize();
|
encoding.as_mut().zeroize();
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
@ -106,9 +106,9 @@ pub trait Ciphersuite:
|
||||||
reader.read_exact(encoding.as_mut())?;
|
reader.read_exact(encoding.as_mut())?;
|
||||||
|
|
||||||
let point = Option::<Self::G>::from(Self::G::from_bytes(&encoding))
|
let point = Option::<Self::G>::from(Self::G::from_bytes(&encoding))
|
||||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid point"))?;
|
.ok_or_else(|| io::Error::other("invalid point"))?;
|
||||||
if point.to_bytes().as_ref() != encoding.as_ref() {
|
if point.to_bytes().as_ref() != encoding.as_ref() {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "non-canonical point"))?;
|
Err(io::Error::other("non-canonical point"))?;
|
||||||
}
|
}
|
||||||
Ok(point)
|
Ok(point)
|
||||||
}
|
}
|
||||||
|
|
|
@ -306,8 +306,7 @@ mod lib {
|
||||||
/// Read keys from a type satisfying std::io::Read.
|
/// Read keys from a type satisfying std::io::Read.
|
||||||
pub fn read<R: io::Read>(reader: &mut R) -> io::Result<ThresholdCore<C>> {
|
pub fn read<R: io::Read>(reader: &mut R) -> io::Result<ThresholdCore<C>> {
|
||||||
{
|
{
|
||||||
let different =
|
let different = || io::Error::other("deserializing ThresholdCore for another curve");
|
||||||
|| io::Error::new(io::ErrorKind::Other, "deserializing ThresholdCore for another curve");
|
|
||||||
|
|
||||||
let mut id_len = [0; 4];
|
let mut id_len = [0; 4];
|
||||||
reader.read_exact(&mut id_len)?;
|
reader.read_exact(&mut id_len)?;
|
||||||
|
@ -331,8 +330,7 @@ mod lib {
|
||||||
(
|
(
|
||||||
read_u16()?,
|
read_u16()?,
|
||||||
read_u16()?,
|
read_u16()?,
|
||||||
Participant::new(read_u16()?)
|
Participant::new(read_u16()?).ok_or(io::Error::other("invalid participant index"))?,
|
||||||
.ok_or(io::Error::new(io::ErrorKind::Other, "invalid participant index"))?,
|
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -344,8 +342,7 @@ mod lib {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ThresholdCore::new(
|
Ok(ThresholdCore::new(
|
||||||
ThresholdParams::new(t, n, i)
|
ThresholdParams::new(t, n, i).map_err(|_| io::Error::other("invalid parameters"))?,
|
||||||
.map_err(|_| io::Error::new(io::ErrorKind::Other, "invalid parameters"))?,
|
|
||||||
secret_share,
|
secret_share,
|
||||||
verification_shares,
|
verification_shares,
|
||||||
))
|
))
|
||||||
|
|
|
@ -55,11 +55,9 @@ pub(crate) fn read_point<R: Read, G: PrimeGroup>(r: &mut R) -> io::Result<G> {
|
||||||
let mut repr = G::Repr::default();
|
let mut repr = G::Repr::default();
|
||||||
r.read_exact(repr.as_mut())?;
|
r.read_exact(repr.as_mut())?;
|
||||||
let point = G::from_bytes(&repr);
|
let point = G::from_bytes(&repr);
|
||||||
let Some(point) = Option::<G>::from(point) else {
|
let Some(point) = Option::<G>::from(point) else { Err(io::Error::other("invalid point"))? };
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "invalid point"))?
|
|
||||||
};
|
|
||||||
if point.to_bytes().as_ref() != repr.as_ref() {
|
if point.to_bytes().as_ref() != repr.as_ref() {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "non-canonical point"))?;
|
Err(io::Error::other("non-canonical point"))?;
|
||||||
}
|
}
|
||||||
Ok(point)
|
Ok(point)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ use ff::{Field, PrimeField};
|
||||||
use group::prime::PrimeGroup;
|
use group::prime::PrimeGroup;
|
||||||
|
|
||||||
#[cfg(feature = "serialize")]
|
#[cfg(feature = "serialize")]
|
||||||
use std::io::{self, ErrorKind, Error, Read, Write};
|
use std::io::{self, Error, Read, Write};
|
||||||
|
|
||||||
/// A cross-group DLEq proof capable of proving that two public keys, across two different curves,
|
/// A cross-group DLEq proof capable of proving that two public keys, across two different curves,
|
||||||
/// share a private key.
|
/// share a private key.
|
||||||
|
@ -91,7 +91,7 @@ fn read_scalar<R: Read, F: PrimeField>(r: &mut R) -> io::Result<F> {
|
||||||
r.read_exact(repr.as_mut())?;
|
r.read_exact(repr.as_mut())?;
|
||||||
let scalar = F::from_repr(repr);
|
let scalar = F::from_repr(repr);
|
||||||
if scalar.is_none().into() {
|
if scalar.is_none().into() {
|
||||||
Err(Error::new(ErrorKind::Other, "invalid scalar"))?;
|
Err(Error::other("invalid scalar"))?;
|
||||||
}
|
}
|
||||||
Ok(scalar.unwrap())
|
Ok(scalar.unwrap())
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,7 @@ pub trait Curve: Ciphersuite {
|
||||||
fn read_G<R: Read>(reader: &mut R) -> io::Result<Self::G> {
|
fn read_G<R: Read>(reader: &mut R) -> io::Result<Self::G> {
|
||||||
let res = <Self as Ciphersuite>::read_G(reader)?;
|
let res = <Self as Ciphersuite>::read_G(reader)?;
|
||||||
if res.is_identity().into() {
|
if res.is_identity().into() {
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "identity point"))?;
|
Err(io::Error::other("identity point"))?;
|
||||||
}
|
}
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,7 +223,7 @@ impl<C: Curve> Commitments<C> {
|
||||||
let dleq = MultiDLEqProof::read(reader, dleq_generators.len())?;
|
let dleq = MultiDLEqProof::read(reader, dleq_generators.len())?;
|
||||||
dleq
|
dleq
|
||||||
.verify(&mut dleq_transcript::<T>(context), &dleq_generators, &dleq_nonces)
|
.verify(&mut dleq_transcript::<T>(context), &dleq_generators, &dleq_nonces)
|
||||||
.map_err(|_| io::Error::new(io::ErrorKind::Other, "invalid DLEq proof"))?;
|
.map_err(|_| io::Error::other("invalid DLEq proof"))?;
|
||||||
Some(dleq)
|
Some(dleq)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -184,8 +184,7 @@ impl TransactionTrait<Bitcoin> for Transaction {
|
||||||
buf
|
buf
|
||||||
}
|
}
|
||||||
fn read<R: io::Read>(reader: &mut R) -> io::Result<Self> {
|
fn read<R: io::Read>(reader: &mut R) -> io::Result<Self> {
|
||||||
Transaction::consensus_decode(reader)
|
Transaction::consensus_decode(reader).map_err(|e| io::Error::other(format!("{e}")))
|
||||||
.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("{e}")))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -223,12 +222,10 @@ impl EventualityTrait for Eventuality {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read<R: io::Read>(reader: &mut R) -> io::Result<Self> {
|
fn read<R: io::Read>(reader: &mut R) -> io::Result<Self> {
|
||||||
let plan_binding_input = OutPoint::consensus_decode(reader).map_err(|_| {
|
let plan_binding_input = OutPoint::consensus_decode(reader)
|
||||||
io::Error::new(io::ErrorKind::Other, "couldn't decode outpoint in eventuality")
|
.map_err(|_| io::Error::other("couldn't decode outpoint in eventuality"))?;
|
||||||
})?;
|
let outputs = Vec::<TxOut>::consensus_decode(reader)
|
||||||
let outputs = Vec::<TxOut>::consensus_decode(reader).map_err(|_| {
|
.map_err(|_| io::Error::other("couldn't decode outputs in eventuality"))?;
|
||||||
io::Error::new(io::ErrorKind::Other, "couldn't decode outputs in eventuality")
|
|
||||||
})?;
|
|
||||||
Ok(Eventuality { plan_binding_input, outputs })
|
Ok(Eventuality { plan_binding_input, outputs })
|
||||||
}
|
}
|
||||||
fn serialize(&self) -> Vec<u8> {
|
fn serialize(&self) -> Vec<u8> {
|
||||||
|
|
|
@ -94,7 +94,7 @@ impl OutputType {
|
||||||
1 => OutputType::Branch,
|
1 => OutputType::Branch,
|
||||||
2 => OutputType::Change,
|
2 => OutputType::Change,
|
||||||
3 => OutputType::Forwarded,
|
3 => OutputType::Forwarded,
|
||||||
_ => Err(io::Error::new(io::ErrorKind::Other, "invalid OutputType"))?,
|
_ => Err(io::Error::other("invalid OutputType"))?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ impl<N: Network> Payment<N> {
|
||||||
.address
|
.address
|
||||||
.clone()
|
.clone()
|
||||||
.try_into()
|
.try_into()
|
||||||
.map_err(|_| io::Error::new(io::ErrorKind::Other, "address couldn't be serialized"))?;
|
.map_err(|_| io::Error::other("address couldn't be serialized"))?;
|
||||||
writer.write_all(&u32::try_from(address.len()).unwrap().to_le_bytes())?;
|
writer.write_all(&u32::try_from(address.len()).unwrap().to_le_bytes())?;
|
||||||
writer.write_all(&address)?;
|
writer.write_all(&address)?;
|
||||||
|
|
||||||
|
@ -52,8 +52,7 @@ impl<N: Network> Payment<N> {
|
||||||
reader.read_exact(&mut buf)?;
|
reader.read_exact(&mut buf)?;
|
||||||
let mut address = vec![0; usize::try_from(u32::from_le_bytes(buf)).unwrap()];
|
let mut address = vec![0; usize::try_from(u32::from_le_bytes(buf)).unwrap()];
|
||||||
reader.read_exact(&mut address)?;
|
reader.read_exact(&mut address)?;
|
||||||
let address = N::Address::try_from(address)
|
let address = N::Address::try_from(address).map_err(|_| io::Error::other("invalid address"))?;
|
||||||
.map_err(|_| io::Error::new(io::ErrorKind::Other, "invalid address"))?;
|
|
||||||
|
|
||||||
let mut buf = [0; 1];
|
let mut buf = [0; 1];
|
||||||
reader.read_exact(&mut buf)?;
|
reader.read_exact(&mut buf)?;
|
||||||
|
@ -68,7 +67,7 @@ impl<N: Network> Payment<N> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let balance = Balance::decode(&mut scale::IoReader(reader))
|
let balance = Balance::decode(&mut scale::IoReader(reader))
|
||||||
.map_err(|_| io::Error::new(io::ErrorKind::Other, "invalid balance"))?;
|
.map_err(|_| io::Error::other("invalid balance"))?;
|
||||||
|
|
||||||
Ok(Payment { address, data, balance })
|
Ok(Payment { address, data, balance })
|
||||||
}
|
}
|
||||||
|
@ -152,13 +151,10 @@ impl<N: Network> Plan<N> {
|
||||||
// TODO: Have Plan construction fail if change cannot be serialized
|
// TODO: Have Plan construction fail if change cannot be serialized
|
||||||
let change = if let Some(change) = &self.change {
|
let change = if let Some(change) = &self.change {
|
||||||
change.clone().try_into().map_err(|_| {
|
change.clone().try_into().map_err(|_| {
|
||||||
io::Error::new(
|
io::Error::other(format!(
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!(
|
|
||||||
"an address we said to use as change couldn't be convered to a Vec<u8>: {}",
|
"an address we said to use as change couldn't be convered to a Vec<u8>: {}",
|
||||||
change.to_string(),
|
change.to_string(),
|
||||||
),
|
))
|
||||||
)
|
|
||||||
})?
|
})?
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
|
@ -188,14 +184,12 @@ impl<N: Network> Plan<N> {
|
||||||
reader.read_exact(&mut len)?;
|
reader.read_exact(&mut len)?;
|
||||||
let mut change = vec![0; usize::from(len[0])];
|
let mut change = vec![0; usize::from(len[0])];
|
||||||
reader.read_exact(&mut change)?;
|
reader.read_exact(&mut change)?;
|
||||||
let change = if change.is_empty() {
|
let change =
|
||||||
|
if change.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(N::Address::try_from(change).map_err(|_| {
|
Some(N::Address::try_from(change).map_err(|_| {
|
||||||
io::Error::new(
|
io::Error::other("couldn't deserialize an Address serialized into a Plan")
|
||||||
io::ErrorKind::Other,
|
|
||||||
"couldn't deserialize an Address serialized into a Plan",
|
|
||||||
)
|
|
||||||
})?)
|
})?)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue