-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add explorer library #651
add explorer library #651
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
[package] | ||
name = "chain-explorer" | ||
version = "0.1.0" | ||
authors = ["[email protected]"] | ||
edition = "2018" | ||
license = "MIT OR Apache-2.0" | ||
repository = "https://github.com/input-output-hk/chain-libs" | ||
|
||
[dependencies] | ||
thiserror = "1.0.20" | ||
tracing = "0.1" | ||
rand = "0.8.3" | ||
rand_chacha = "0.3.1" | ||
sanakirja = "1.2.5" | ||
zerocopy = "0.5.0" | ||
byteorder = "1.4.3" | ||
hex = "0.4.3" | ||
|
||
chain-core = { path = "../chain-core" } | ||
chain-addr = { path = "../chain-addr" } | ||
chain-crypto = { path = "../chain-crypto" } | ||
chain-impl-mockchain = { path = "../chain-impl-mockchain" } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
use crate::chain_storable::{Choice, VotePlanId}; | ||
use sanakirja::{direct_repr, Storable, UnsizedStorable}; | ||
use std::mem; | ||
use zerocopy::AsBytes; | ||
|
||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] | ||
#[repr(C)] | ||
pub struct TransactionCertificate { | ||
tag: CertificateTag, | ||
cert: SerializedCertificate, | ||
} | ||
|
||
impl TransactionCertificate { | ||
pub fn from_vote_plan_id(id: VotePlanId) -> Self { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, not really... The graphql API should return a It could be called |
||
TransactionCertificate { | ||
tag: CertificateTag::VotePlan, | ||
cert: SerializedCertificate { vote_plan: id }, | ||
} | ||
} | ||
|
||
pub fn from_public_vote_cast(vote: PublicVoteCast) -> Self { | ||
TransactionCertificate { | ||
tag: CertificateTag::PublicVoteCast, | ||
cert: SerializedCertificate { | ||
public_vote_cast: vote, | ||
}, | ||
} | ||
} | ||
|
||
pub fn from_private_vote_cast(vote: PrivateVoteCast) -> Self { | ||
TransactionCertificate { | ||
tag: CertificateTag::PrivateVoteCast, | ||
cert: SerializedCertificate { | ||
private_vote_cast: vote, | ||
}, | ||
} | ||
} | ||
|
||
pub fn as_vote_plan(&self) -> Option<&VotePlanId> { | ||
unsafe { | ||
match self { | ||
Self { | ||
tag: CertificateTag::VotePlan, | ||
cert: SerializedCertificate { vote_plan }, | ||
} => Some(vote_plan), | ||
_ => None, | ||
} | ||
} | ||
} | ||
|
||
pub fn as_public_vote_cast(&self) -> Option<&PublicVoteCast> { | ||
unsafe { | ||
match self { | ||
Self { | ||
tag: CertificateTag::PublicVoteCast, | ||
cert: SerializedCertificate { public_vote_cast }, | ||
} => Some(public_vote_cast), | ||
_ => None, | ||
} | ||
} | ||
} | ||
|
||
pub fn as_private_vote_cast(&self) -> Option<&PrivateVoteCast> { | ||
unsafe { | ||
match self { | ||
Self { | ||
tag: CertificateTag::PrivateVoteCast, | ||
cert: SerializedCertificate { private_vote_cast }, | ||
} => Some(private_vote_cast), | ||
_ => None, | ||
} | ||
} | ||
} | ||
} | ||
|
||
direct_repr!(TransactionCertificate); | ||
|
||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, AsBytes)] | ||
#[repr(u8)] | ||
pub(crate) enum CertificateTag { | ||
VotePlan = 0, | ||
PublicVoteCast = 1, | ||
PrivateVoteCast = 2, | ||
} | ||
|
||
#[repr(C)] | ||
#[derive(Clone, Copy)] | ||
union SerializedCertificate { | ||
vote_plan: VotePlanId, | ||
public_vote_cast: PublicVoteCast, | ||
private_vote_cast: PrivateVoteCast, | ||
} | ||
|
||
impl SerializedCertificate { | ||
fn as_bytes(&self) -> &[u8; mem::size_of::<Self>()] { | ||
unsafe { std::mem::transmute(self) } | ||
} | ||
} | ||
|
||
impl PartialEq for SerializedCertificate { | ||
fn eq(&self, other: &Self) -> bool { | ||
self.as_bytes().eq(other.as_bytes()) | ||
} | ||
} | ||
|
||
impl Eq for SerializedCertificate {} | ||
|
||
impl PartialOrd for SerializedCertificate { | ||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { | ||
self.as_bytes().partial_cmp(other.as_bytes()) | ||
} | ||
} | ||
|
||
impl Ord for SerializedCertificate { | ||
fn cmp(&self, other: &Self) -> std::cmp::Ordering { | ||
self.as_bytes().cmp(other.as_bytes()) | ||
} | ||
} | ||
|
||
impl std::fmt::Debug for SerializedCertificate { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
f.write_str(&hex::encode(self.as_bytes())) | ||
} | ||
} | ||
|
||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, AsBytes)] | ||
#[repr(C)] | ||
pub struct PublicVoteCast { | ||
pub vote_plan_id: VotePlanId, | ||
pub proposal_index: u8, | ||
pub choice: Choice, | ||
} | ||
|
||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, AsBytes)] | ||
#[repr(C)] | ||
pub struct PrivateVoteCast { | ||
pub vote_plan_id: VotePlanId, | ||
pub proposal_index: u8, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the advantage of an union + discriminant over an enum?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just that I don't need a
max
const fn to compute the size of the serialized thing...There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be clear though, it is possible to store the whole thing as a
data_len + tag + data
, I just went with a fixed-size thing because it's easier to write (no need to deserialize, or use a DST), and for that theunion
gave me less trouble.