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
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions dash/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ serde_derive = "1.0.103"
secp256k1 = { features = [ "recovery", "rand", "hashes" ], version="0.30.0" }
bip39 = "2.0.0"
bincode_test = {package = "bincode", version= "1.3.3" }
assert_matches = "1.5.0"

[[example]]
name = "bip32"
Expand Down
5 changes: 5 additions & 0 deletions dash/examples/handshake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use dashcore::consensus::{Decodable, encode};
use dashcore::network::{address, constants, message, message_network};
use dashcore::secp256k1;
use dashcore::secp256k1::rand::Rng;
use secp256k1::rand;

fn main() {
// This example establishes a connection to a Bitcoin node, sends the intial
Expand Down Expand Up @@ -97,6 +98,9 @@ fn build_version_message(address: SocketAddr) -> message::NetworkMessage {
// "The last block received by the emitting node"
let start_height: i32 = 0;

// Generate challenge for masternode authentication
let mn_auth_challenge = rand::random();

// Construct the message
message::NetworkMessage::Version(message_network::VersionMessage::new(
services,
Expand All @@ -106,5 +110,6 @@ fn build_version_message(address: SocketAddr) -> message::NetworkMessage {
nonce,
user_agent,
start_height,
mn_auth_challenge,
))
}
28 changes: 23 additions & 5 deletions dash/src/consensus/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,25 @@ use internals::write_err;

use crate::bip152::{PrefilledTransaction, ShortId};
use crate::blockdata::transaction::Transaction;
use crate::hash_types::{BlockHash, FilterHash, FilterHeader, TxMerkleNode};
use crate::bls_sig_utils::BLSSignature;
use crate::hash_types::{
BlockHash, FilterHash, FilterHeader, MerkleRootMasternodeList, TxMerkleNode,
};
use crate::io::{self, Cursor, Read};
use crate::network::message_sml::DeletedQuorum;
#[cfg(feature = "std")]
use crate::network::{
address::{AddrV2Message, Address},
message_blockdata::Inventory,
};
use crate::prelude::*;
use crate::sml::entry::MasternodeListEntry;
use crate::taproot::TapLeafHash;
use crate::transaction::special_transaction::TransactionType;
use crate::transaction::special_transaction::quorum_commitment::QuorumFinalizationCommitment;
use crate::transaction::txin::TxIn;
use crate::transaction::txout::TxOut;
use crate::{OutPoint, ScriptBuf, address};
use crate::{OutPoint, ProTxHash, ScriptBuf, address};

/// Encoding error.
#[derive(Debug)]
Expand Down Expand Up @@ -104,11 +110,13 @@ pub enum Error {
Hex(hashes::hex::Error),
/// Address error
Address(address::Error),
/// Invalid enum value
InvalidEnumValue { max: u16, received: u16, msg: String },
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
match self {
Error::Io(ref e) => write_err!(f, "IO error"; e),
Error::OversizedVectorAllocation { requested: ref r, max: ref m } => {
write!(f, "allocation of oversized vector: requested {}, maximum {}", r, m)
Expand All @@ -135,6 +143,9 @@ impl fmt::Display for Error {
}
Error::Hex(ref e) => write!(f, "hex error {}", e),
Error::Address(ref e) => write!(f, "address error {}", e),
Error::InvalidEnumValue { max, received, msg } => {
write!(f, "invalid enum value, max: {} received: {} ({})", max, received, msg)
}
}
}
}
Expand All @@ -155,8 +166,9 @@ impl std::error::Error for Error {
| Error::WrongSpecialTransactionPayloadConversion { .. }
| Error::NonStandardScriptPayout(..)
| Error::InvalidVectorSize { .. }
| Error::Hex(_) => None,
Error::Address(_) => None,
| Error::Hex(_)
| Error::Address(_)
| InvalidEnumValue { .. } => None,
}
}
}
Expand Down Expand Up @@ -673,6 +685,12 @@ impl_vec!(VarInt);
impl_vec!(ShortId);
impl_vec!(OutPoint);
impl_vec!(PrefilledTransaction);
impl_vec!(QuorumFinalizationCommitment);
impl_vec!(DeletedQuorum);
impl_vec!(BLSSignature);
impl_vec!(ProTxHash);
impl_vec!(MerkleRootMasternodeList);
impl_vec!(MasternodeListEntry);

#[cfg(feature = "std")]
impl_vec!(Inventory);
Expand Down
11 changes: 8 additions & 3 deletions dash/src/consensus/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use serde::de::{SeqAccess, Unexpected, Visitor};
use serde::ser::SerializeSeq;
use serde::{Deserializer, Serializer};

use super::encode::Error as ConsensusError;
use super::encode::{Error as ConsensusError, Error};
use super::{Decodable, Encodable};
use crate::alloc::string::ToString;
use crate::io;
Expand Down Expand Up @@ -411,6 +411,10 @@ fn consensus_error_into_serde<E: serde::de::Error>(error: ConsensusError) -> E {
),
ConsensusError::Hex(error) => E::custom(error),
ConsensusError::Address(error) => E::custom(error),
ConsensusError::InvalidEnumValue { max, received, msg } => E::invalid_value(
Unexpected::Unsigned(received.into()),
&DisplayExpected(format_args!("expected enum value ≤ {}: {}", max, msg)),
),
}
}

Expand Down Expand Up @@ -455,8 +459,9 @@ impl<E: fmt::Debug, I: Iterator<Item = Result<u8, E>>> IterReader<E, I> {
match (result, self.error) {
(Ok(_), None) if self.iterator.next().is_some() => Err(DecodeError::TooManyBytes),
(Ok(value), None) => Ok(value),
(Ok(_), Some(error)) =>
panic!("{} silently ate the error: {:?}", core::any::type_name::<T>(), error),
(Ok(_), Some(error)) => {
panic!("{} silently ate the error: {:?}", core::any::type_name::<T>(), error)
}
(Err(ConsensusError::Io(io_error)), Some(de_error))
if io_error.kind() == io::ErrorKind::Other && io_error.source().is_none() =>
Err(DecodeError::Other(de_error)),
Expand Down
10 changes: 6 additions & 4 deletions dash/src/crypto/sighash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,12 @@ impl fmt::Display for Error {
f,
"A single prevout has been provided but all prevouts are needed without `ANYONECANPAY`"
),
WrongAnnex =>
write!(f, "Annex must be at least one byte long and the first bytes must be `0x50`"),
InvalidSighashType(hash_ty) =>
write!(f, "Invalid taproot signature hash type : {} ", hash_ty),
WrongAnnex => {
write!(f, "Annex must be at least one byte long and the first bytes must be `0x50`")
}
InvalidSighashType(hash_ty) => {
write!(f, "Invalid taproot signature hash type : {} ", hash_ty)
}
}
}
}
Expand Down
33 changes: 30 additions & 3 deletions dash/src/hash_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,6 @@ mod newtypes {
/// A dash witness transaction ID.
pub struct Wtxid(sha256d::Hash);




/// A hash of a public key.
pub struct PubkeyHash(hash160::Hash);
/// A hash of Dash Script bytecode.
Expand Down Expand Up @@ -145,6 +142,8 @@ mod newtypes {
/// ProTxHash is a pro-tx hash
#[hash_newtype(forward)]
pub struct ProTxHash(sha256d::Hash);
pub struct ConfirmedHash(sha256d::Hash);
pub struct Sha256dHash(sha256d::Hash);
}

impl_hashencode!(Txid);
Expand All @@ -169,6 +168,10 @@ mod newtypes {
impl_hashencode!(PubkeyHash);
impl_hashencode!(CycleHash);

impl_hashencode!(ConfirmedHash);
impl_hashencode!(ProTxHash);
impl_hashencode!(Sha256dHash);

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

impl Txid {
Expand All @@ -195,6 +198,30 @@ mod newtypes {
}
}

impl ConfirmedHash {
/// Create a ConfirmedHash from a string
pub fn from_hex(s: &str) -> Result<ConfirmedHash, Error> {
Ok(Self(sha256d::Hash::from_str(s)?))
}

/// Convert a ConfirmedHash to a string
pub fn to_hex(&self) -> String {
self.0.to_string()
}
}

impl Sha256dHash {
/// Create a Sha256dHash from a string
pub fn from_hex(s: &str) -> Result<Sha256dHash, Error> {
Ok(Self(sha256d::Hash::from_str(s)?))
}

/// Convert a ConfirmedHash to a string
pub fn to_hex(&self) -> String {
self.0.to_string()
}
}

impl InputsHash {
/// Create an InputsHash from a string
pub fn from_hex(s: &str) -> Result<InputsHash, Error> {
Expand Down
1 change: 1 addition & 0 deletions dash/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ pub mod pow;
pub mod psbt;
pub mod sign_message;
pub mod signer;
pub mod sml;
pub mod string;
pub mod taproot;
pub mod util;
Expand Down
25 changes: 18 additions & 7 deletions dash/src/network/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use crate::merkle_tree::MerkleBlock;
use crate::network::address::{AddrV2Message, Address};
use crate::network::{
message_blockdata, message_bloom, message_compact_blocks, message_filter, message_network,
message_sml,
};
use crate::prelude::*;

Expand Down Expand Up @@ -236,7 +237,10 @@ pub enum NetworkMessage {
AddrV2(Vec<AddrV2Message>),
/// `sendaddrv2`
SendAddrV2,

/// `getmnlistd`
GetMnListD(message_sml::GetMnListDiff),
/// `mnlistdiff`
MnListDiff(message_sml::MnListDiff),
/// Any other message.
Unknown {
/// The command of this message.
Expand Down Expand Up @@ -290,6 +294,8 @@ impl NetworkMessage {
NetworkMessage::WtxidRelay => "wtxidrelay",
NetworkMessage::AddrV2(_) => "addrv2",
NetworkMessage::SendAddrV2 => "sendaddrv2",
NetworkMessage::GetMnListD(_) => "getmnlistd",
NetworkMessage::MnListDiff(_) => "mnlistdiff",
NetworkMessage::Unknown { .. } => "unknown",
}
}
Expand Down Expand Up @@ -373,6 +379,8 @@ impl Encodable for RawNetworkMessage {
| NetworkMessage::FilterClear
| NetworkMessage::SendAddrV2 => vec![],
NetworkMessage::Unknown { payload: ref data, .. } => serialize(data),
NetworkMessage::GetMnListD(ref dat) => serialize(dat),
NetworkMessage::MnListDiff(ref dat) => serialize(dat),
})
.consensus_encode(w)?;
Ok(len)
Expand Down Expand Up @@ -498,6 +506,12 @@ impl Decodable for RawNetworkMessage {
"addrv2" =>
NetworkMessage::AddrV2(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
"sendaddrv2" => NetworkMessage::SendAddrV2,
"getmnlistd" => NetworkMessage::GetMnListD(
Decodable::consensus_decode_from_finite_reader(&mut mem_d)?,
),
"mnlistdiff" => NetworkMessage::MnListDiff(
Decodable::consensus_decode_from_finite_reader(&mut mem_d)?,
),
_ => NetworkMessage::Unknown { command: cmd, payload: mem_d.into_inner() },
};
Ok(RawNetworkMessage { magic, payload })
Expand Down Expand Up @@ -756,10 +770,8 @@ mod test {
0x10, 0x2f, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68,
0x69, 0x3a, 0x30, 0x2e, 0x31, 0x37, 0x2e, 0x31,
0x2f, 0x93, 0x8c, 0x08, 0x00, 0x01
]);
]).expect("deserialize version message");

assert!(msg.is_ok());
let msg = msg.unwrap();
assert_eq!(msg.magic, 0xd9b4bef9);
if let NetworkMessage::Version(version_msg) = msg.payload {
assert_eq!(version_msg.version, 70015);
Expand Down Expand Up @@ -801,10 +813,9 @@ mod test {
0x69, 0x3a, 0x30, 0x2e, 0x31, 0x37, 0x2e, 0x31,
0x2f, 0x93, 0x8c, 0x08, 0x00, 0x01, 0x00, 0x00
];
let msg = deserialize_partial::<RawNetworkMessage>(&data);
assert!(msg.is_ok());
let (msg, consumed) =
deserialize_partial::<RawNetworkMessage>(&data).expect("deserialize partial message");

let (msg, consumed) = msg.unwrap();
assert_eq!(consumed, data.to_vec().len() - 2);
assert_eq!(msg.magic, 0xd9b4bef9);
if let NetworkMessage::Version(version_msg) = msg.payload {
Expand Down
Loading
Loading