Cleanup redundant AsFixedBytes and FixedLength traits (#3131)
* no need for AsFixedBytes we can just use AsRef<[u8]> * cleanup FixedLength trait * revert this change for now * fix store tests * cleanup and fix tests after rebase * fix tests * update based on PR review less hard-coded values now * cleanup
This commit is contained in:
@@ -26,14 +26,14 @@ use crate::core::{
|
||||
use crate::global;
|
||||
use crate::pow::{verify_size, Difficulty, Proof, ProofOfWork};
|
||||
use crate::ser::{
|
||||
self, deserialize_default, serialize_default, FixedLength, PMMRable, Readable, Reader,
|
||||
Writeable, Writer,
|
||||
self, deserialize_default, serialize_default, PMMRable, Readable, Reader, Writeable, Writer,
|
||||
};
|
||||
use chrono::naive::{MAX_DATE, MIN_DATE};
|
||||
use chrono::prelude::{DateTime, NaiveDateTime, Utc};
|
||||
use chrono::Duration;
|
||||
use keychain::{self, BlindingFactor};
|
||||
use std::collections::HashSet;
|
||||
use std::convert::TryInto;
|
||||
use std::fmt;
|
||||
use std::iter::FromIterator;
|
||||
use std::sync::Arc;
|
||||
@@ -168,10 +168,6 @@ impl Writeable for HeaderEntry {
|
||||
}
|
||||
}
|
||||
|
||||
impl FixedLength for HeaderEntry {
|
||||
const LEN: usize = Hash::LEN + 8 + Difficulty::LEN + 4 + 1;
|
||||
}
|
||||
|
||||
impl Hashed for HeaderEntry {
|
||||
/// The hash of the underlying block.
|
||||
fn hash(&self) -> Hash {
|
||||
@@ -265,6 +261,12 @@ impl PMMRable for BlockHeader {
|
||||
is_secondary: self.pow.is_secondary(),
|
||||
}
|
||||
}
|
||||
|
||||
// Size is hash + u64 + difficulty + u32 + u8.
|
||||
fn elmt_size() -> Option<u16> {
|
||||
const LEN: usize = Hash::LEN + 8 + Difficulty::LEN + 4 + 1;
|
||||
Some(LEN.try_into().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
/// Serialization of a block header
|
||||
|
||||
+6
-10
@@ -17,9 +17,7 @@
|
||||
//! Primary hash function used in the protocol
|
||||
//!
|
||||
|
||||
use crate::ser::{
|
||||
self, AsFixedBytes, Error, FixedLength, ProtocolVersion, Readable, Reader, Writeable, Writer,
|
||||
};
|
||||
use crate::ser::{self, Error, ProtocolVersion, Readable, Reader, Writeable, Writer};
|
||||
use blake2::blake2b::Blake2b;
|
||||
use byteorder::{BigEndian, ByteOrder};
|
||||
use std::cmp::min;
|
||||
@@ -52,12 +50,10 @@ impl fmt::Display for Hash {
|
||||
}
|
||||
}
|
||||
|
||||
impl FixedLength for Hash {
|
||||
/// Size of a hash in bytes.
|
||||
const LEN: usize = 32;
|
||||
}
|
||||
|
||||
impl Hash {
|
||||
/// A hash is 32 bytes.
|
||||
pub const LEN: usize = 32;
|
||||
|
||||
/// Builds a Hash from a byte vector. If the vector is too short, it will be
|
||||
/// completed by zeroes. If it's too long, it will be truncated.
|
||||
pub fn from_vec(v: &[u8]) -> Hash {
|
||||
@@ -196,8 +192,8 @@ impl ser::Writer for HashWriter {
|
||||
ser::SerializationMode::Hash
|
||||
}
|
||||
|
||||
fn write_fixed_bytes<T: AsFixedBytes>(&mut self, b32: &T) -> Result<(), ser::Error> {
|
||||
self.state.update(b32.as_ref());
|
||||
fn write_fixed_bytes<T: AsRef<[u8]>>(&mut self, bytes: T) -> Result<(), ser::Error> {
|
||||
self.state.update(bytes.as_ref());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -19,14 +19,15 @@ use crate::core::verifier_cache::VerifierCache;
|
||||
use crate::core::{committed, Committed};
|
||||
use crate::libtx::secp_ser;
|
||||
use crate::ser::{
|
||||
self, read_multi, FixedLength, PMMRable, ProtocolVersion, Readable, Reader,
|
||||
VerifySortedAndUnique, Writeable, Writer,
|
||||
self, read_multi, PMMRable, ProtocolVersion, Readable, Reader, VerifySortedAndUnique,
|
||||
Writeable, Writer,
|
||||
};
|
||||
use crate::{consensus, global};
|
||||
use enum_primitive::FromPrimitive;
|
||||
use keychain::{self, BlindingFactor};
|
||||
use std::cmp::Ordering;
|
||||
use std::cmp::{max, min};
|
||||
use std::convert::TryInto;
|
||||
use std::sync::Arc;
|
||||
use std::{error, fmt};
|
||||
use util;
|
||||
@@ -352,12 +353,10 @@ impl PMMRable for TxKernel {
|
||||
fn as_elmt(&self) -> Self::E {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
/// Kernels are "variable size" but we need to implement FixedLength for legacy reasons.
|
||||
/// At some point we will refactor the MMR backend so this is no longer required.
|
||||
impl FixedLength for TxKernel {
|
||||
const LEN: usize = 0;
|
||||
fn elmt_size() -> Option<u16> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl KernelFeatures {
|
||||
@@ -1430,6 +1429,14 @@ impl PMMRable for Output {
|
||||
fn as_elmt(&self) -> OutputIdentifier {
|
||||
OutputIdentifier::from_output(self)
|
||||
}
|
||||
|
||||
fn elmt_size() -> Option<u16> {
|
||||
Some(
|
||||
(1 + secp::constants::PEDERSEN_COMMITMENT_SIZE)
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl OutputFeatures {
|
||||
@@ -1549,10 +1556,6 @@ impl OutputIdentifier {
|
||||
}
|
||||
}
|
||||
|
||||
impl FixedLength for OutputIdentifier {
|
||||
const LEN: usize = 1 + secp::constants::PEDERSEN_COMMITMENT_SIZE;
|
||||
}
|
||||
|
||||
impl Writeable for OutputIdentifier {
|
||||
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
|
||||
self.features.write(writer)?;
|
||||
|
||||
@@ -17,7 +17,7 @@ use crate::core::hash::{DefaultHashable, Hashed};
|
||||
use crate::global;
|
||||
use crate::pow::common::EdgeType;
|
||||
use crate::pow::error::Error;
|
||||
use crate::ser::{self, FixedLength, Readable, Reader, Writeable, Writer};
|
||||
use crate::ser::{self, Readable, Reader, Writeable, Writer};
|
||||
use rand::{thread_rng, Rng};
|
||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||
/// Types for a Cuck(at)oo proof of work and its encapsulation as a fully usable
|
||||
@@ -156,8 +156,9 @@ impl Readable for Difficulty {
|
||||
}
|
||||
}
|
||||
|
||||
impl FixedLength for Difficulty {
|
||||
const LEN: usize = 8;
|
||||
impl Difficulty {
|
||||
/// Difficulty is 8 bytes.
|
||||
pub const LEN: usize = 8;
|
||||
}
|
||||
|
||||
impl Serialize for Difficulty {
|
||||
|
||||
+22
-126
@@ -23,10 +23,10 @@ use crate::core::hash::{DefaultHashable, Hash, Hashed};
|
||||
use crate::global::PROTOCOL_VERSION;
|
||||
use byteorder::{BigEndian, ByteOrder, ReadBytesExt};
|
||||
use keychain::{BlindingFactor, Identifier, IDENTIFIER_SIZE};
|
||||
use std::convert::TryInto;
|
||||
use std::fmt::{self, Debug};
|
||||
use std::io::{self, Read, Write};
|
||||
use std::marker;
|
||||
use std::{cmp, error};
|
||||
use std::{cmp, error, marker};
|
||||
use util::secp::constants::{
|
||||
AGG_SIGNATURE_SIZE, COMPRESSED_PUBLIC_KEY_SIZE, MAX_PROOF_SIZE, PEDERSEN_COMMITMENT_SIZE,
|
||||
SECRET_KEY_SIZE,
|
||||
@@ -179,14 +179,13 @@ pub trait Writer {
|
||||
|
||||
/// Writes a variable number of bytes. The length is encoded as a 64-bit
|
||||
/// prefix.
|
||||
fn write_bytes<T: AsFixedBytes>(&mut self, bytes: &T) -> Result<(), Error> {
|
||||
fn write_bytes<T: AsRef<[u8]>>(&mut self, bytes: T) -> Result<(), Error> {
|
||||
self.write_u64(bytes.as_ref().len() as u64)?;
|
||||
self.write_fixed_bytes(bytes)
|
||||
}
|
||||
|
||||
/// Writes a fixed number of bytes from something that can turn itself into
|
||||
/// a `&[u8]`. The reader is expected to know the actual length on read.
|
||||
fn write_fixed_bytes<T: AsFixedBytes>(&mut self, fixed: &T) -> Result<(), Error>;
|
||||
/// Writes a fixed number of bytes. The reader is expected to know the actual length on read.
|
||||
fn write_fixed_bytes<T: AsRef<[u8]>>(&mut self, bytes: T) -> Result<(), Error>;
|
||||
}
|
||||
|
||||
/// Implementations defined how different numbers and binary structures are
|
||||
@@ -567,15 +566,11 @@ impl Writeable for BlindingFactor {
|
||||
|
||||
impl Readable for BlindingFactor {
|
||||
fn read(reader: &mut dyn Reader) -> Result<BlindingFactor, Error> {
|
||||
let bytes = reader.read_fixed_bytes(BlindingFactor::LEN)?;
|
||||
let bytes = reader.read_fixed_bytes(SECRET_KEY_SIZE)?;
|
||||
Ok(BlindingFactor::from_slice(&bytes))
|
||||
}
|
||||
}
|
||||
|
||||
impl FixedLength for BlindingFactor {
|
||||
const LEN: usize = SECRET_KEY_SIZE;
|
||||
}
|
||||
|
||||
impl Writeable for Identifier {
|
||||
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
writer.write_fixed_bytes(self)
|
||||
@@ -609,24 +604,24 @@ impl Readable for RangeProof {
|
||||
}
|
||||
}
|
||||
|
||||
impl FixedLength for RangeProof {
|
||||
const LEN: usize = 8 // length prefix
|
||||
+ MAX_PROOF_SIZE;
|
||||
}
|
||||
|
||||
impl PMMRable for RangeProof {
|
||||
type E = Self;
|
||||
|
||||
fn as_elmt(&self) -> Self::E {
|
||||
self.clone()
|
||||
}
|
||||
|
||||
// Size is length prefix (8 bytes for u64) + MAX_PROOF_SIZE.
|
||||
fn elmt_size() -> Option<u16> {
|
||||
Some((8 + MAX_PROOF_SIZE).try_into().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl Readable for Signature {
|
||||
fn read(reader: &mut dyn Reader) -> Result<Signature, Error> {
|
||||
let a = reader.read_fixed_bytes(Signature::LEN)?;
|
||||
let mut c = [0; Signature::LEN];
|
||||
c[..Signature::LEN].clone_from_slice(&a[..Signature::LEN]);
|
||||
let a = reader.read_fixed_bytes(AGG_SIGNATURE_SIZE)?;
|
||||
let mut c = [0; AGG_SIGNATURE_SIZE];
|
||||
c[..AGG_SIGNATURE_SIZE].clone_from_slice(&a[..AGG_SIGNATURE_SIZE]);
|
||||
Ok(Signature::from_raw_data(&c).unwrap())
|
||||
}
|
||||
}
|
||||
@@ -637,19 +632,11 @@ impl Writeable for Signature {
|
||||
}
|
||||
}
|
||||
|
||||
impl FixedLength for Signature {
|
||||
const LEN: usize = AGG_SIGNATURE_SIZE;
|
||||
}
|
||||
|
||||
impl FixedLength for PublicKey {
|
||||
const LEN: usize = COMPRESSED_PUBLIC_KEY_SIZE;
|
||||
}
|
||||
|
||||
impl Writeable for PublicKey {
|
||||
// Write the public key in compressed form
|
||||
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
let secp = Secp256k1::with_caps(ContextFlag::None);
|
||||
writer.write_fixed_bytes(&self.serialize_vec(&secp, true).as_ref())?;
|
||||
writer.write_fixed_bytes(self.serialize_vec(&secp, true))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -657,7 +644,7 @@ impl Writeable for PublicKey {
|
||||
impl Readable for PublicKey {
|
||||
// Read the public key in compressed form
|
||||
fn read(reader: &mut dyn Reader) -> Result<Self, Error> {
|
||||
let buf = reader.read_fixed_bytes(PublicKey::LEN)?;
|
||||
let buf = reader.read_fixed_bytes(COMPRESSED_PUBLIC_KEY_SIZE)?;
|
||||
let secp = Secp256k1::with_caps(ContextFlag::None);
|
||||
let pk = PublicKey::from_slice(&secp, &buf).map_err(|_| Error::CorruptedData)?;
|
||||
Ok(pk)
|
||||
@@ -709,9 +696,8 @@ impl<'a> Writer for BinWriter<'a> {
|
||||
SerializationMode::Full
|
||||
}
|
||||
|
||||
fn write_fixed_bytes<T: AsFixedBytes>(&mut self, fixed: &T) -> Result<(), Error> {
|
||||
let bs = fixed.as_ref();
|
||||
self.sink.write_all(bs)?;
|
||||
fn write_fixed_bytes<T: AsRef<[u8]>>(&mut self, bytes: T) -> Result<(), Error> {
|
||||
self.sink.write_all(bytes.as_ref())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -838,20 +824,17 @@ impl Writeable for [u8; 4] {
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for types that serialize to a known fixed length.
|
||||
pub trait FixedLength {
|
||||
/// The length in bytes
|
||||
const LEN: usize;
|
||||
}
|
||||
|
||||
/// Trait for types that can be added to a PMMR.
|
||||
pub trait PMMRable: Writeable + Clone + Debug + DefaultHashable {
|
||||
/// The type of element actually stored in the MMR data file.
|
||||
/// This allows us to store Hash elements in the header MMR for variable size BlockHeaders.
|
||||
type E: FixedLength + Readable + Writeable + Debug;
|
||||
type E: Readable + Writeable + Debug;
|
||||
|
||||
/// Convert the pmmrable into the element to be stored in the MMR data file.
|
||||
fn as_elmt(&self) -> Self::E;
|
||||
|
||||
/// Size of each element if "fixed" size. Elements are "variable" size if None.
|
||||
fn elmt_size() -> Option<u16>;
|
||||
}
|
||||
|
||||
/// Generic trait to ensure PMMR elements can be hashed with an index
|
||||
@@ -866,93 +849,6 @@ impl<T: DefaultHashable> PMMRIndexHashable for T {
|
||||
}
|
||||
}
|
||||
|
||||
/// Useful marker trait on types that can be sized byte slices
|
||||
pub trait AsFixedBytes: Sized + AsRef<[u8]> {
|
||||
/// The length in bytes
|
||||
fn len(&self) -> usize;
|
||||
}
|
||||
|
||||
impl<'a> AsFixedBytes for &'a [u8] {
|
||||
fn len(&self) -> usize {
|
||||
1
|
||||
}
|
||||
}
|
||||
impl AsFixedBytes for Vec<u8> {
|
||||
fn len(&self) -> usize {
|
||||
self.len()
|
||||
}
|
||||
}
|
||||
impl AsFixedBytes for [u8; 1] {
|
||||
fn len(&self) -> usize {
|
||||
1
|
||||
}
|
||||
}
|
||||
impl AsFixedBytes for [u8; 2] {
|
||||
fn len(&self) -> usize {
|
||||
2
|
||||
}
|
||||
}
|
||||
impl AsFixedBytes for [u8; 4] {
|
||||
fn len(&self) -> usize {
|
||||
4
|
||||
}
|
||||
}
|
||||
impl AsFixedBytes for [u8; 6] {
|
||||
fn len(&self) -> usize {
|
||||
6
|
||||
}
|
||||
}
|
||||
impl AsFixedBytes for [u8; 8] {
|
||||
fn len(&self) -> usize {
|
||||
8
|
||||
}
|
||||
}
|
||||
impl AsFixedBytes for [u8; 20] {
|
||||
fn len(&self) -> usize {
|
||||
20
|
||||
}
|
||||
}
|
||||
impl AsFixedBytes for [u8; 32] {
|
||||
fn len(&self) -> usize {
|
||||
32
|
||||
}
|
||||
}
|
||||
impl AsFixedBytes for String {
|
||||
fn len(&self) -> usize {
|
||||
self.len()
|
||||
}
|
||||
}
|
||||
impl AsFixedBytes for crate::core::hash::Hash {
|
||||
fn len(&self) -> usize {
|
||||
32
|
||||
}
|
||||
}
|
||||
impl AsFixedBytes for util::secp::pedersen::RangeProof {
|
||||
fn len(&self) -> usize {
|
||||
self.plen
|
||||
}
|
||||
}
|
||||
impl AsFixedBytes for util::secp::Signature {
|
||||
fn len(&self) -> usize {
|
||||
64
|
||||
}
|
||||
}
|
||||
impl AsFixedBytes for util::secp::pedersen::Commitment {
|
||||
fn len(&self) -> usize {
|
||||
PEDERSEN_COMMITMENT_SIZE
|
||||
}
|
||||
}
|
||||
impl AsFixedBytes for BlindingFactor {
|
||||
fn len(&self) -> usize {
|
||||
SECRET_KEY_SIZE
|
||||
}
|
||||
}
|
||||
impl AsFixedBytes for keychain::Identifier {
|
||||
fn len(&self) -> usize {
|
||||
IDENTIFIER_SIZE
|
||||
}
|
||||
}
|
||||
|
||||
// serializer for io::Errorkind, originally auto-generated by serde-derive
|
||||
// slightly modified to handle the #[non_exhaustive] tag on io::ErrorKind
|
||||
fn serialize_error_kind<S>(
|
||||
|
||||
Reference in New Issue
Block a user