Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion dash/src/consensus/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use core::{fmt, mem, u32};

use hashes::{sha256, sha256d, hash_x11, Hash, hash160};
use internals::write_err;
use crate::{address, ScriptBuf};
use crate::{address, OutPoint, ScriptBuf};
use crate::transaction::special_transaction::TransactionType;
use crate::bip152::{PrefilledTransaction, ShortId};
use crate::transaction::{txin::TxIn, txout::TxOut};
Expand Down Expand Up @@ -672,6 +672,7 @@ impl_vec!(u64);
impl_vec!(TapLeafHash);
impl_vec!(VarInt);
impl_vec!(ShortId);
impl_vec!(OutPoint);
impl_vec!(PrefilledTransaction);

#[cfg(feature = "std")]
Expand Down
121 changes: 59 additions & 62 deletions dash/src/ephemerealdata/instant_lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@
//! confirm transaction within 1 or 2 seconds. This data structure
//! represents a p2p message containing a data to verify such a lock.

use consensus::{Decodable, Encodable, encode};
use consensus::encode::MAX_VEC_SIZE;
use ::{io, Txid};
use core::fmt::{Debug, Formatter};
use crate::io;

#[cfg(all(not(feature = "std"), not(test)))]
use alloc::vec::Vec;
use core::fmt::{Debug, Formatter};
#[cfg(any(feature = "std", test))]
pub use std::vec::Vec;
use blockdata::transaction::OutPoint;

type BlsSignature = [u8; 96];
use hashes::{Hash, HashEngine};
use crate::hash_types::{CycleHash, QuorumSigningRequestId};
use crate::{OutPoint, Txid, VarInt};
use crate::bls_sig_utils::BLSSignature;
Comment thread
shotonoff marked this conversation as resolved.
use crate::consensus::{Encodable};
use crate::internal_macros::impl_consensus_encoding;

type CycleHash = [u8; 32];
const IS_LOCK_REQUEST_ID_PREFIX: &str = "islock";

#[derive(Clone, Eq, PartialEq)]
/// Instant send lock is a mechanism used by the Dash network to
Expand All @@ -30,18 +32,32 @@ pub struct InstantLock {
/// Hash to figure out which quorum was used to sign this IS lock
pub cyclehash: CycleHash,
/// Quorum signature for this IS lock
pub signature: BlsSignature,
pub signature: BLSSignature,
}

impl Default for InstantLock {
fn default() -> Self {
Self {
version: 1,
inputs: Default::default(),
txid: Default::default(),
cyclehash: Default::default(),
signature: [0; 96]
impl_consensus_encoding!(InstantLock, version, inputs, txid, cyclehash, signature);

impl InstantLock {
/// Returns quorum signing request ID
pub fn request_id(&self) -> Result<QuorumSigningRequestId, io::Error> {
let mut engine = QuorumSigningRequestId::engine();

// Prefix
let prefix_len = VarInt(IS_LOCK_REQUEST_ID_PREFIX.len() as u64);
prefix_len.consensus_encode(&mut engine)?;

engine.input(IS_LOCK_REQUEST_ID_PREFIX.as_bytes());

// Inputs
let inputs_len = VarInt(self.inputs.len() as u64);
inputs_len.consensus_encode(&mut engine)?;

for input in &self.inputs {
engine.input(&input.txid[..]);
engine.input(&input.vout.to_le_bytes());
}

Ok(QuorumSigningRequestId::from_engine(engine))
}
}

Comment thread
shotonoff marked this conversation as resolved.
Expand All @@ -52,43 +68,16 @@ impl Debug for InstantLock {
.field("inputs", &format_args!("{:?}", self.inputs))
.field("txid", &format_args!("{}", self.txid))
.field("cyclehash", &format_args!("{:?}", self.cyclehash))
.field("signature", &format_args!("{:?}", self.signature.to_vec()))
.field("signature", &format_args!("{:?}", self.signature.as_bytes()))
.finish()
}
}

impl Decodable for InstantLock {
fn consensus_decode<D: io::Read>(d: D) -> Result<Self, encode::Error> {
let mut d = d.take(MAX_VEC_SIZE as u64);
let version = u8::consensus_decode(&mut d)?;
let inputs = Vec::<OutPoint>::consensus_decode(&mut d)?;
let txid = Txid::consensus_decode(&mut d)?;
let cyclehash = <[u8; 32]>::consensus_decode(&mut d)?;
let signature = <[u8; 96]>::consensus_decode(&mut d)?;

Ok(Self {
version, inputs, txid, cyclehash, signature
})
}
}

impl Encodable for InstantLock {
fn consensus_encode<S: io::Write>(&self, mut s: S) -> Result<usize, io::Error> {
let mut len = 0;
len += self.version.consensus_encode(&mut s)?;
len += self.inputs.consensus_encode(&mut s)?;
len += self.txid.consensus_encode(&mut s)?;
len += self.cyclehash.consensus_encode(&mut s)?;
len += self.signature.consensus_encode(&mut s)?;
Ok(len)
}
}

#[cfg(test)]
mod is_lock_test {
use hashes::hex::{FromHex, ToHex};
use consensus::{deserialize, serialize};
use ephemerealdata::instant_lock::InstantLock;
mod tests {
use super::*;
use crate::consensus::{deserialize, serialize};
Comment thread
shotonoff marked this conversation as resolved.
use crate::internal_macros::hex;

#[test]
pub fn should_decode_vec() {
Expand All @@ -105,26 +94,34 @@ mod is_lock_test {
// cyclehash: "7c30826123d0f29fe4c4a8895d7ba4eb469b1fafa6ad7b23896a1a591766a536",
// signature: "85e12d70ca7118c5034004f93e45384079f46c6c2928b45cfc5d3ad640e70dfd87a9a3069899adfb3b1622daeeead19809b74354272ccf95290678f55c13728e3c5ee8f8417fcce3dfdca2a7c9c33ec981abdff1ec35a2e4b558c3698f01c1b8"
// };
let vec = Vec::from_hex(hex).unwrap();

let vec = hex!(hex);

// let expected_hash = "4ee6a4ed2b6c70efd401c6c91dfaf6c61badd13f80ec07c281bb93d5270fcd58";
// let expected_request_id = "495be44677e82895a9396fef02c6e9afc1f01d4aff70622b9f78e0e10d57064c";

let is_lock: InstantLock = deserialize(&vec).unwrap();
assert_eq!(is_lock.version, 1);

// TODO: check outpoints

let mut cycle_clone = is_lock.cyclehash.clone();
cycle_clone.reverse();
assert_eq!(cycle_clone.to_hex(), "7c30826123d0f29fe4c4a8895d7ba4eb469b1fafa6ad7b23896a1a591766a536");
assert_eq!(is_lock.cyclehash.to_string(), "7c30826123d0f29fe4c4a8895d7ba4eb469b1fafa6ad7b23896a1a591766a536");

let mut signature_clone = is_lock.signature.clone();
signature_clone.reverse();
//assert_eq!(signature_clone.to_hex(), "85e12d70ca7118c5034004f93e45384079f46c6c2928b45cfc5d3ad640e70dfd87a9a3069899adfb3b1622daeeead19809b74354272ccf95290678f55c13728e3c5ee8f8417fcce3dfdca2a7c9c33ec981abdff1ec35a2e4b558c3698f01c1b8");

let serialized = serialize(&is_lock).to_hex();
assert_eq!(serialized, hex);
let serialized = serialize(&is_lock);
assert_eq!(serialized, vec);
}

#[test]
pub fn should_create_request_id() {
let hex = "010101102862a43d122e6675aba4b507ae307af8e1e17febc77907e08b3efa28f41b000000004b446de00a592c67402c0a65649f4ad69f29084b3e9054f5aa6b85a50b497fe136a56617591a6a89237bada6af1f9b46eba47b5d89a8c4e49ff2d0236182307c85e12d70ca7118c5034004f93e45384079f46c6c2928b45cfc5d3ad640e70dfd87a9a3069899adfb3b1622daeeead19809b74354272ccf95290678f55c13728e3c5ee8f8417fcce3dfdca2a7c9c33ec981abdff1ec35a2e4b558c3698f01c1b8";
let vec = hex!(hex);

let expected_request_id = "495be44677e82895a9396fef02c6e9afc1f01d4aff70622b9f78e0e10d57064c";

let is_lock: InstantLock = deserialize(vec.as_slice()).unwrap();

let request_id = is_lock.request_id().expect("should return request id");
assert_eq!(request_id.to_string(), expected_request_id);
}

// #[test]
Expand All @@ -146,4 +143,4 @@ mod is_lock_test {
//
// let is_lock: InstantLock = serde_json::from_str(str).unwrap();
// }
}
}
11 changes: 7 additions & 4 deletions dash/src/hash_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,10 @@ mod newtypes {
use core::str::FromStr;
use hashes::{sha256, sha256d, hash160, hash_x11, hash_newtype, Hash};
use hashes::hex::Error;
use internals::hex::Case;
use internals::hex::display::DisplayHex;
use crate::prelude::String;

hash_newtype! {
/// A dash transaction hash/transaction ID.
///
pub struct Txid(sha256d::Hash);

/// A dash witness transaction ID.
Expand Down Expand Up @@ -126,9 +123,13 @@ mod newtypes {
pub struct QuorumHash(sha256d::Hash);
/// A hash of a quorum verification vector
pub struct QuorumVVecHash(sha256d::Hash);
/// A hash of a quorum signing request id
pub struct QuorumSigningRequestId(sha256d::Hash);
/// ProTxHash is a pro-tx hash
#[hash_newtype(forward)]
pub struct ProTxHash(sha256d::Hash);
/// CycleHash is a cycle hash
pub struct CycleHash(hash_x11::Hash);
}

impl_hashencode!(Txid);
Expand All @@ -149,7 +150,9 @@ mod newtypes {

impl_hashencode!(QuorumHash);
impl_hashencode!(QuorumVVecHash);
impl_hashencode!(QuorumSigningRequestId);
impl_hashencode!(PubkeyHash);
impl_hashencode!(CycleHash);

impl_asref_push_bytes!(PubkeyHash, ScriptHash, WPubkeyHash, WScriptHash);

Expand Down Expand Up @@ -204,7 +207,7 @@ mod newtypes {

/// Convert a PubkeyHash to a string
pub fn to_hex(&self) -> String {
self.0.as_byte_array().to_hex_string(Case::Lower)
self.0.to_string()
}
}
}
1 change: 1 addition & 0 deletions dash/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ pub mod taproot;
pub mod util;
pub mod bls_sig_utils;
mod signer;
mod ephemerealdata;

// May depend on crate features and we don't want to bother with it
#[allow(unused)]
Expand Down