use crate::grin_core::core::FeeFields;
use crate::grin_core::core::{Input, Output, TxKernel};
use crate::grin_core::libtx::secp_ser;
use crate::grin_keychain::{BlindingFactor, Identifier};
use crate::grin_util::secp;
use crate::grin_util::secp::key::PublicKey;
use crate::grin_util::secp::pedersen::{Commitment, RangeProof};
use crate::grin_util::secp::Signature;
use crate::{slate_versions::ser, CbData};
use ed25519_dalek::PublicKey as DalekPublicKey;
use ed25519_dalek::Signature as DalekSignature;
use uuid::Uuid;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct SlateV4 {
#[serde(with = "ser::version_info_v4")]
pub ver: VersionCompatInfoV4,
pub id: Uuid,
#[serde(with = "ser::slate_state_v4")]
pub sta: SlateStateV4,
#[serde(
serialize_with = "secp_ser::as_hex",
deserialize_with = "secp_ser::blind_from_hex"
)]
#[serde(default = "default_offset_zero")]
#[serde(skip_serializing_if = "offset_is_zero")]
pub off: BlindingFactor,
#[serde(default = "default_num_participants_2")]
#[serde(skip_serializing_if = "num_parts_is_2")]
pub num_parts: u8,
#[serde(with = "secp_ser::string_or_u64")]
#[serde(skip_serializing_if = "u64_is_blank")]
#[serde(default = "default_u64_0")]
pub amt: u64,
#[serde(skip_serializing_if = "fee_is_zero")]
#[serde(default = "default_fee")]
pub fee: FeeFields,
#[serde(skip_serializing_if = "u8_is_blank")]
#[serde(default = "default_u8_0")]
pub feat: u8,
#[serde(with = "secp_ser::string_or_u64")]
#[serde(skip_serializing_if = "u64_is_blank")]
#[serde(default = "default_u64_0")]
pub ttl: u64,
pub sigs: Vec<ParticipantDataV4>,
#[serde(default = "default_coms_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub coms: Option<Vec<CommitsV4>>,
#[serde(default = "default_payment_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub proof: Option<PaymentInfoV4>,
#[serde(default = "default_kernel_features_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub feat_args: Option<KernelFeaturesArgsV4>,
}
fn default_payment_none() -> Option<PaymentInfoV4> {
None
}
fn default_offset_zero() -> BlindingFactor {
BlindingFactor::zero()
}
fn offset_is_zero(o: &BlindingFactor) -> bool {
*o == BlindingFactor::zero()
}
fn default_coms_none() -> Option<Vec<CommitsV4>> {
None
}
fn default_u64_0() -> u64 {
0
}
fn num_parts_is_2(n: &u8) -> bool {
*n == 2
}
fn default_num_participants_2() -> u8 {
2
}
fn default_kernel_features_none() -> Option<KernelFeaturesArgsV4> {
None
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum SlateStateV4 {
Unknown,
Standard1,
Standard2,
Standard3,
Invoice1,
Invoice2,
Invoice3,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct KernelFeaturesArgsV4 {
pub lock_hgt: u64,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct VersionCompatInfoV4 {
pub version: u16,
pub block_header_version: u16,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct ParticipantDataV4 {
#[serde(with = "secp_ser::pubkey_serde")]
pub xs: PublicKey,
#[serde(with = "secp_ser::pubkey_serde")]
pub nonce: PublicKey,
#[serde(default = "default_part_sig_none")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(with = "secp_ser::option_sig_serde")]
pub part: Option<Signature>,
}
fn default_part_sig_none() -> Option<Signature> {
None
}
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
pub struct PaymentInfoV4 {
#[serde(with = "ser::dalek_pubkey_serde")]
pub saddr: DalekPublicKey,
#[serde(with = "ser::dalek_pubkey_serde")]
pub raddr: DalekPublicKey,
#[serde(default = "default_receiver_signature_none")]
#[serde(with = "ser::option_dalek_sig_serde")]
#[serde(skip_serializing_if = "Option::is_none")]
pub rsig: Option<DalekSignature>,
}
fn default_receiver_signature_none() -> Option<DalekSignature> {
None
}
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub struct CommitsV4 {
#[serde(default = "default_output_feature")]
#[serde(skip_serializing_if = "output_feature_is_plain")]
pub f: OutputFeaturesV4,
#[serde(
serialize_with = "secp_ser::as_hex",
deserialize_with = "secp_ser::commitment_from_hex"
)]
pub c: Commitment,
#[serde(with = "ser::option_rangeproof_hex")]
#[serde(default = "default_range_proof")]
#[serde(skip_serializing_if = "Option::is_none")]
pub p: Option<RangeProof>,
}
impl From<&Output> for CommitsV4 {
fn from(out: &Output) -> CommitsV4 {
CommitsV4 {
f: out.features().into(),
c: out.commitment(),
p: Some(out.proof()),
}
}
}
impl From<&Input> for CommitsV4 {
fn from(input: &Input) -> CommitsV4 {
CommitsV4 {
f: input.features.into(),
c: input.commitment(),
p: None,
}
}
}
fn default_output_feature() -> OutputFeaturesV4 {
OutputFeaturesV4(0)
}
fn output_feature_is_plain(o: &OutputFeaturesV4) -> bool {
o.0 == 0
}
#[derive(Serialize, Deserialize, Copy, Debug, Clone, PartialEq, Eq)]
pub struct OutputFeaturesV4(pub u8);
pub fn sig_is_blank(s: &secp::Signature) -> bool {
for b in s.to_raw_data().iter() {
if *b != 0 {
return false;
}
}
true
}
fn default_range_proof() -> Option<RangeProof> {
None
}
fn u64_is_blank(u: &u64) -> bool {
*u == 0
}
fn default_u8_0() -> u8 {
0
}
fn u8_is_blank(u: &u8) -> bool {
*u == 0
}
fn fee_is_zero(f: &FeeFields) -> bool {
f.is_zero()
}
fn default_fee() -> FeeFields {
FeeFields::zero()
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct CoinbaseV4 {
output: CbOutputV4,
kernel: CbKernelV4,
key_id: Option<Identifier>,
}
impl From<CbData> for CoinbaseV4 {
fn from(cb: CbData) -> CoinbaseV4 {
CoinbaseV4 {
output: CbOutputV4::from(&cb.output),
kernel: CbKernelV4::from(&cb.kernel),
key_id: cb.key_id,
}
}
}
impl From<&Output> for CbOutputV4 {
fn from(output: &Output) -> CbOutputV4 {
CbOutputV4 {
features: CbOutputFeatures::Coinbase,
commit: output.commitment(),
proof: output.proof(),
}
}
}
impl From<&TxKernel> for CbKernelV4 {
fn from(kernel: &TxKernel) -> CbKernelV4 {
CbKernelV4 {
features: CbKernelFeatures::Coinbase,
excess: kernel.excess,
excess_sig: kernel.excess_sig,
}
}
}
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
enum CbOutputFeatures {
Coinbase,
}
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
enum CbKernelFeatures {
Coinbase,
}
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
struct CbOutputV4 {
features: CbOutputFeatures,
#[serde(serialize_with = "secp_ser::as_hex")]
commit: Commitment,
#[serde(serialize_with = "secp_ser::as_hex")]
proof: RangeProof,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
struct CbKernelV4 {
features: CbKernelFeatures,
#[serde(serialize_with = "secp_ser::as_hex")]
excess: Commitment,
#[serde(with = "secp_ser::sig_serde")]
excess_sig: secp::Signature,
}