Skip to content
This repository has been archived by the owner on Jun 11, 2022. It is now read-only.

Commit

Permalink
Add serde deserialization for Ledger
Browse files Browse the repository at this point in the history
  • Loading branch information
edolstra committed Jun 13, 2019
1 parent 3c67376 commit 9993620
Show file tree
Hide file tree
Showing 29 changed files with 234 additions and 41 deletions.
17 changes: 16 additions & 1 deletion chain-addr/src/lib.rs
Expand Up @@ -51,7 +51,9 @@ cfg_if! {
// Allow to differentiate between address in
// production and testing setting, so that
// one type of address is not used in another setting.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde_derive::Serialize)]
#[derive(
Debug, Clone, Copy, PartialEq, Eq, Hash, serde_derive::Serialize, serde_derive::Deserialize,
)]
pub enum Discrimination {
Production,
Test,
Expand Down Expand Up @@ -456,6 +458,19 @@ impl serde::Serialize for Address {
}
}

impl<'de> serde::Deserialize<'de> for Address {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(
AddressReadable::from_string(&String::deserialize(deserializer)?)
.unwrap()
.to_address(),
)
}
}

fn chain_crypto_err(e: chain_crypto::PublicKeyError) -> ReadError {
match e {
PublicKeyError::SizeInvalid => {
Expand Down
9 changes: 9 additions & 0 deletions chain-crypto/src/key.rs
Expand Up @@ -259,6 +259,15 @@ impl<A: AsymmetricPublicKey> serde::Serialize for PublicKey<A> {
}
}

impl<'de, A: AsymmetricPublicKey> serde::Deserialize<'de> for PublicKey<A> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(Self::try_from_bech32_str(&String::deserialize(deserializer)?).unwrap())
}
}

#[cfg(test)]
mod test {
use super::*;
Expand Down
12 changes: 11 additions & 1 deletion chain-impl-mockchain/src/account.rs
Expand Up @@ -11,7 +11,17 @@ pub use account::{LedgerError, SpendingCounter};
pub type AccountAlg = Ed25519;

/// Account Identifier (also used as Public Key)
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, serde_derive::Serialize)]
#[derive(
Debug,
Clone,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
serde_derive::Serialize,
serde_derive::Deserialize,
)]
pub struct Identifier(PublicKey<AccountAlg>);

impl From<PublicKey<AccountAlg>> for Identifier {
Expand Down
6 changes: 3 additions & 3 deletions chain-impl-mockchain/src/accounting/account.rs
Expand Up @@ -37,7 +37,7 @@ impl From<InsertError> for LedgerError {
}
}

#[derive(Clone, serde_derive::Serialize)]
#[derive(Clone, PartialEq, Eq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct AccountState<Extra> {
counter: SpendingCounter,
delegation: Option<StakePoolId>,
Expand Down Expand Up @@ -126,7 +126,7 @@ impl<Extra: Clone> AccountState<Extra> {
/// the counter is incremented. A matching counter
/// needs to be used in the spending phase to make
/// sure we have non-replayability of a transaction.
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde_derive::Serialize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct SpendingCounter(u32);

impl SpendingCounter {
Expand Down Expand Up @@ -166,7 +166,7 @@ impl<'a, ID, Extra> Iterator for Iter<'a, ID, Extra> {
}

/// The public ledger of all accounts associated with their current state
#[derive(Clone, serde_derive::Serialize)]
#[derive(Clone, PartialEq, Eq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct Ledger<ID: Hash + Eq, Extra>(Hamt<DefaultHasher, ID, AccountState<Extra>>);

impl<ID: Clone + Eq + Hash, Extra: Clone> Ledger<ID, Extra> {
Expand Down
13 changes: 12 additions & 1 deletion chain-impl-mockchain/src/block/header.rs
Expand Up @@ -31,7 +31,18 @@ pub struct Common {
pub chain_length: ChainLength,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, serde_derive::Serialize)]
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
serde_derive::Serialize,
serde_derive::Deserialize,
)]
pub struct ChainLength(pub(crate) u32);

/// FIXME SECURITY : we want to sign Common + everything in proof except the signature
Expand Down
1 change: 1 addition & 0 deletions chain-impl-mockchain/src/block/version.rs
Expand Up @@ -84,6 +84,7 @@ impl BlockVersion {
Ord,
Hash,
serde_derive::Serialize,
serde_derive::Deserialize,
)]
pub enum ConsensusVersion {
#[strum(to_string = "bft")]
Expand Down
4 changes: 2 additions & 2 deletions chain-impl-mockchain/src/config.rs
Expand Up @@ -42,7 +42,7 @@ impl Into<ReadError> for Error {
}
}

#[derive(Clone, Debug, Eq, PartialEq, serde_derive::Serialize)]
#[derive(Clone, Debug, Eq, PartialEq, serde_derive::Serialize, serde_derive::Deserialize)]
pub enum ConfigParam {
Block0Date(Block0Date),
Discrimination(Discrimination),
Expand Down Expand Up @@ -201,7 +201,7 @@ trait ConfigParamVariant: Clone + Eq + PartialEq {
}

/// Seconds elapsed since 1-Jan-1970 (unix time)
#[derive(Debug, Clone, Copy, Eq, PartialEq, serde_derive::Serialize)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct Block0Date(pub u64);

impl ConfigParamVariant for Block0Date {
Expand Down
13 changes: 12 additions & 1 deletion chain-impl-mockchain/src/date.rs
Expand Up @@ -6,7 +6,18 @@ use std::{error, fmt, num::ParseIntError, str};
/// Non unique identifier of the transaction position in the
/// blockchain. There may be many transactions related to the same
/// `SlotId`.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, serde_derive::Serialize)]
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
serde_derive::Serialize,
serde_derive::Deserialize,
)]
pub struct BlockDate {
pub epoch: Epoch,
pub slot_id: SlotId,
Expand Down
11 changes: 10 additions & 1 deletion chain-impl-mockchain/src/fee.rs
Expand Up @@ -5,7 +5,16 @@ use chain_addr::Address;

/// Linear fee using the basic affine formula
/// `COEFFICIENT * bytes(COUNT(tx.inputs) + COUNT(tx.outputs)) + CONSTANT + CERTIFICATE*COUNT(certificates)`.
#[derive(PartialEq, Eq, PartialOrd, Debug, Clone, Copy, serde_derive::Serialize)]
#[derive(
PartialEq,
Eq,
PartialOrd,
Debug,
Clone,
Copy,
serde_derive::Serialize,
serde_derive::Deserialize,
)]
pub struct LinearFee {
pub constant: u64,
pub coefficient: u64,
Expand Down
12 changes: 10 additions & 2 deletions chain-impl-mockchain/src/key.rs
Expand Up @@ -6,7 +6,6 @@ use chain_core::property;
use chain_crypto as crypto;
use chain_crypto::{AsymmetricKey, AsymmetricPublicKey, SigningAlgorithm, VerificationAlgorithm};

use base64;
use std::str::FromStr;

pub type SpendingPublicKey = crypto::PublicKey<crypto::Ed25519>;
Expand Down Expand Up @@ -230,7 +229,16 @@ impl serde::Serialize for Hash {
{
// FIXME: we don't want to encode as a string in binary
// serialization formats.
serializer.serialize_str(&base64::encode(self.as_ref()))
serializer.serialize_str(&format!("{}", self.0))
}
}

impl<'de> serde::Deserialize<'de> for Hash {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(Self::from_str(&String::deserialize(deserializer)?).unwrap())
}
}

Expand Down
2 changes: 1 addition & 1 deletion chain-impl-mockchain/src/leadership/bft.rs
Expand Up @@ -11,7 +11,7 @@ use std::sync::Arc;

pub type BftVerificationAlg = Ed25519;

#[derive(Debug, Clone, PartialEq, Eq, Hash, serde_derive::Serialize)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct LeaderId(pub(crate) PublicKey<BftVerificationAlg>);

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand Down
2 changes: 1 addition & 1 deletion chain-impl-mockchain/src/leadership/genesis/mod.rs
Expand Up @@ -16,7 +16,7 @@ pub use vrfeval::{ActiveSlotsCoeff, ActiveSlotsCoeffError, Nonce, Witness, Witne
use vrfeval::{PercentStake, VrfEvaluator};

/// Praos Leader consisting of the KES public key and VRF public key
#[derive(Debug, Clone, PartialEq, Eq, Hash, serde_derive::Serialize)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct GenesisPraosLeader {
pub kes_public_key: PublicKey<SumEd25519_12>,
pub vrf_public_key: PublicKey<Curve25519_2HashDH>,
Expand Down
27 changes: 25 additions & 2 deletions chain-impl-mockchain/src/leadership/genesis/vrfeval.rs
Expand Up @@ -14,7 +14,7 @@ use std::error::Error;
use std::fmt::{self, Display, Formatter};

/// Nonce gathered per block
#[derive(Debug, Clone, PartialEq, Eq, serde_derive::Serialize)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Nonce([u8; 32]);

impl Nonce {
Expand All @@ -30,6 +30,29 @@ impl Nonce {
}
}

impl serde::Serialize for Nonce {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
// FIXME: we don't want to encode as a string in binary
// serialization formats.
serializer.serialize_str(&base64::encode(&self.0))
}
}

impl<'de> serde::Deserialize<'de> for Nonce {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let data = base64::decode(&String::deserialize(deserializer)?).unwrap();
let mut buf = [0; 32];
buf.copy_from_slice(&data[0..32]);
Ok(Self(buf))
}
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ActiveSlotsCoeffError {
InvalidValue(Milli),
Expand All @@ -50,7 +73,7 @@ impl Error for ActiveSlotsCoeffError {}
/// Active slots coefficient used for calculating minimum stake to become slot leader candidate
/// Described in Ouroboros Praos paper, also referred to as parameter F of phi function
/// Always in range (0, 1]
#[derive(Clone, Copy, Debug, Eq, PartialEq, serde_derive::Serialize)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct ActiveSlotsCoeff(pub(crate) Milli);

impl TryFrom<Milli> for ActiveSlotsCoeff {
Expand Down
4 changes: 2 additions & 2 deletions chain-impl-mockchain/src/ledger.rs
Expand Up @@ -19,7 +19,7 @@ use std::sync::Arc;
use std::time::{Duration, SystemTime};

// static parameters, effectively this is constant in the parameter of the blockchain
#[derive(Clone, serde_derive::Serialize)]
#[derive(Clone, PartialEq, Eq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct LedgerStaticParameters {
pub block0_initial_hash: HeaderHash,
pub block0_start_time: config::Block0Date,
Expand All @@ -40,7 +40,7 @@ pub struct LedgerParameters {
///
/// The ledger can be easily and cheaply cloned despite containing reference
/// to a lot of data (millions of utxos, thousands of accounts, ..)
#[derive(Clone, serde_derive::Serialize)]
#[derive(Clone, PartialEq, Eq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct Ledger {
pub(crate) utxos: utxo::Ledger<Address>,
pub(crate) oldutxos: utxo::Ledger<legacy::OldAddress>,
Expand Down
2 changes: 1 addition & 1 deletion chain-impl-mockchain/src/message/config.rs
Expand Up @@ -2,7 +2,7 @@ use crate::config::ConfigParam;
use chain_core::mempack::{ReadBuf, ReadError, Readable};
use chain_core::property;

#[derive(Debug, Clone, PartialEq, Eq, serde_derive::Serialize)]
#[derive(Debug, Clone, PartialEq, Eq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct ConfigParams(pub(crate) Vec<ConfigParam>);

impl ConfigParams {
Expand Down
13 changes: 12 additions & 1 deletion chain-impl-mockchain/src/milli.rs
Expand Up @@ -3,7 +3,18 @@ use std::{fmt, iter};

const MILLI_MULTIPLIER: u64 = 1000;

#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd, serde_derive::Serialize)]
#[derive(
Clone,
Copy,
Debug,
Default,
Eq,
Ord,
PartialEq,
PartialOrd,
serde_derive::Serialize,
serde_derive::Deserialize,
)]
pub struct Milli(u64);

impl Milli {
Expand Down
16 changes: 13 additions & 3 deletions chain-impl-mockchain/src/multisig/declaration.rs
Expand Up @@ -5,7 +5,17 @@ use super::index::{Index, TreeIndex, LEVEL_MAXLIMIT};
pub use crate::transaction::WitnessMultisigData;

/// Account Identifier (also used as Public Key)
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, serde_derive::Serialize)]
#[derive(
Debug,
Clone,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
serde_derive::Serialize,
serde_derive::Deserialize,
)]
pub struct Identifier(key::Hash);

impl AsRef<[u8]> for Identifier {
Expand Down Expand Up @@ -39,7 +49,7 @@ impl std::fmt::Display for Identifier {
///
/// * a threshold that need to be between 1 and the size of owners
/// * a bunch of owners which is either a hash of a key, or a sub declaration
#[derive(Debug, Clone, serde_derive::Serialize)]
#[derive(Debug, Clone, PartialEq, Eq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct Declaration {
pub(crate) threshold: u8, // between 1 and len(owners)
pub(crate) owners: Vec<DeclElement>,
Expand All @@ -55,7 +65,7 @@ impl Declaration {
}
}

#[derive(Debug, Clone, serde_derive::Serialize)]
#[derive(Debug, Clone, PartialEq, Eq, serde_derive::Serialize, serde_derive::Deserialize)]
pub enum DeclElement {
Sub(Declaration),
Owner(key::Hash),
Expand Down
2 changes: 1 addition & 1 deletion chain-impl-mockchain/src/multisig/ledger.rs
Expand Up @@ -5,7 +5,7 @@ use super::declaration::{Declaration, DeclarationError, Identifier};
use crate::accounting::account::{self, SpendingCounter};
use crate::value::{Value, ValueError};

#[derive(Clone, serde_derive::Serialize)]
#[derive(Clone, PartialEq, Eq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct Ledger {
// TODO : investigate about merging the declarations and the accounts in
// one with an extension on the account::Ledger
Expand Down
2 changes: 1 addition & 1 deletion chain-impl-mockchain/src/setting.rs
Expand Up @@ -14,7 +14,7 @@ use chain_time::era::TimeEra;
use std::convert::TryFrom;
use std::sync::Arc;

#[derive(Clone, Debug, Eq, PartialEq, serde_derive::Serialize)]
#[derive(Clone, Debug, Eq, PartialEq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct Settings {
pub era: TimeEra,
pub consensus_version: ConsensusVersion,
Expand Down
2 changes: 1 addition & 1 deletion chain-impl-mockchain/src/stake/delegation.rs
Expand Up @@ -7,7 +7,7 @@ use crate::transaction::AccountIdentifier;
pub type PoolTable = Hamt<DefaultHasher, StakePoolId, StakePoolInfo>;

/// A structure that keeps track of stake keys and stake pools.
#[derive(Clone, serde_derive::Serialize)]
#[derive(Clone, PartialEq, Eq, serde_derive::Serialize, serde_derive::Deserialize)]
pub struct DelegationState {
pub(crate) stake_pools: PoolTable,
}
Expand Down

0 comments on commit 9993620

Please sign in to comment.