Merge rust-bitcoin/rust-bitcoin#753: Put rustdocs above attributes
533120899e
Put rustdocs above attributes (Tobin Harding) Pull request description: (Trivial / Very low priority PR) Rust idiomatic style is to put the rustdoc _above_ any attributes on types, functions, etc. Audit the codebase and move comments/attributes to the correct place. Add a trailing full stop at times to neaten things up a little extra. Done after discussion [here](https://github.com/rust-bitcoin/rust-secp256k1/pull/353#discussion_r778393138) ACKs for top commit: Kixunil: ACK533120899e
RCasatta: ACK533120899e
Tree-SHA512: 7cd00dc46de813cbe3f96417bb4b13980064e10110b421224496c8b64bbe87b61b6c757cc621fde1d05754be6ecdc08acdb51fd8978e3f820d2d93f7104062d1
This commit is contained in:
commit
9e7bb0967c
|
@ -42,8 +42,8 @@ use policy::DUST_RELAY_TX_FEE;
|
||||||
use util::ecdsa::PublicKey;
|
use util::ecdsa::PublicKey;
|
||||||
use util::address::WitnessVersion;
|
use util::address::WitnessVersion;
|
||||||
|
|
||||||
|
/// A Bitcoin script.
|
||||||
#[derive(Clone, Default, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
#[derive(Clone, Default, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
||||||
/// A Bitcoin script
|
|
||||||
pub struct Script(Box<[u8]>);
|
pub struct Script(Box<[u8]>);
|
||||||
|
|
||||||
impl AsRef<[u8]> for Script {
|
impl AsRef<[u8]> for Script {
|
||||||
|
@ -101,8 +101,8 @@ impl ::core::str::FromStr for Script {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An object which can be used to construct a script piece by piece.
|
||||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||||
/// An object which can be used to construct a script piece by piece
|
|
||||||
pub struct Builder(Vec<u8>, Option<opcodes::All>);
|
pub struct Builder(Vec<u8>, Option<opcodes::All>);
|
||||||
display_from_debug!(Builder);
|
display_from_debug!(Builder);
|
||||||
|
|
||||||
|
@ -118,17 +118,17 @@ pub enum Error {
|
||||||
EarlyEndOfScript,
|
EarlyEndOfScript,
|
||||||
/// Tried to read an array off the stack as a number when it was more than 4 bytes
|
/// Tried to read an array off the stack as a number when it was more than 4 bytes
|
||||||
NumericOverflow,
|
NumericOverflow,
|
||||||
#[cfg(feature = "bitcoinconsensus")]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))]
|
|
||||||
/// Error validating the script with bitcoinconsensus library
|
/// Error validating the script with bitcoinconsensus library
|
||||||
|
#[cfg(feature = "bitcoinconsensus")]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))]
|
||||||
BitcoinConsensus(bitcoinconsensus::Error),
|
BitcoinConsensus(bitcoinconsensus::Error),
|
||||||
#[cfg(feature = "bitcoinconsensus")]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))]
|
|
||||||
/// Can not find the spent output
|
/// Can not find the spent output
|
||||||
UnknownSpentOutput(OutPoint),
|
|
||||||
#[cfg(feature = "bitcoinconsensus")]
|
#[cfg(feature = "bitcoinconsensus")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))]
|
||||||
|
UnknownSpentOutput(OutPoint),
|
||||||
/// Can not serialize the spending transaction
|
/// Can not serialize the spending transaction
|
||||||
|
#[cfg(feature = "bitcoinconsensus")]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))]
|
||||||
SerializationError
|
SerializationError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,21 +496,21 @@ impl Script {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Shorthand for [Self::verify_with_flags] with flag [bitcoinconsensus::VERIFY_ALL]
|
||||||
#[cfg(feature="bitcoinconsensus")]
|
#[cfg(feature="bitcoinconsensus")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))]
|
||||||
/// Shorthand for [Self::verify_with_flags] with flag [bitcoinconsensus::VERIFY_ALL]
|
|
||||||
pub fn verify (&self, index: usize, amount: ::Amount, spending: &[u8]) -> Result<(), Error> {
|
pub fn verify (&self, index: usize, amount: ::Amount, spending: &[u8]) -> Result<(), Error> {
|
||||||
self.verify_with_flags(index, amount, spending, ::bitcoinconsensus::VERIFY_ALL)
|
self.verify_with_flags(index, amount, spending, ::bitcoinconsensus::VERIFY_ALL)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature="bitcoinconsensus")]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))]
|
|
||||||
/// Verify spend of an input script
|
/// Verify spend of an input script
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `index` - the input index in spending which is spending this transaction
|
/// * `index` - the input index in spending which is spending this transaction
|
||||||
/// * `amount` - the amount this script guards
|
/// * `amount` - the amount this script guards
|
||||||
/// * `spending` - the transaction that attempts to spend the output holding this script
|
/// * `spending` - the transaction that attempts to spend the output holding this script
|
||||||
/// * `flags` - verification flags, see [bitcoinconsensus::VERIFY_ALL] and similar
|
/// * `flags` - verification flags, see [bitcoinconsensus::VERIFY_ALL] and similar
|
||||||
|
#[cfg(feature="bitcoinconsensus")]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))]
|
||||||
pub fn verify_with_flags<F: Into<u32>>(&self, index: usize, amount: ::Amount, spending: &[u8], flags: F) -> Result<(), Error> {
|
pub fn verify_with_flags<F: Into<u32>>(&self, index: usize, amount: ::Amount, spending: &[u8], flags: F) -> Result<(), Error> {
|
||||||
Ok(bitcoinconsensus::verify_with_flags (&self.0[..], amount.as_sat(), spending, index, flags.into())?)
|
Ok(bitcoinconsensus::verify_with_flags (&self.0[..], amount.as_sat(), spending, index, flags.into())?)
|
||||||
}
|
}
|
||||||
|
|
|
@ -506,18 +506,18 @@ impl Transaction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Shorthand for [Self::verify_with_flags] with flag [bitcoinconsensus::VERIFY_ALL]
|
||||||
#[cfg(feature="bitcoinconsensus")]
|
#[cfg(feature="bitcoinconsensus")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))]
|
||||||
/// Shorthand for [Self::verify_with_flags] with flag [bitcoinconsensus::VERIFY_ALL]
|
|
||||||
pub fn verify<S>(&self, spent: S) -> Result<(), script::Error>
|
pub fn verify<S>(&self, spent: S) -> Result<(), script::Error>
|
||||||
where S: FnMut(&OutPoint) -> Option<TxOut> {
|
where S: FnMut(&OutPoint) -> Option<TxOut> {
|
||||||
self.verify_with_flags(spent, ::bitcoinconsensus::VERIFY_ALL)
|
self.verify_with_flags(spent, ::bitcoinconsensus::VERIFY_ALL)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature="bitcoinconsensus")]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))]
|
|
||||||
/// Verify that this transaction is able to spend its inputs
|
/// Verify that this transaction is able to spend its inputs
|
||||||
/// The lambda spent should not return the same TxOut twice!
|
/// The lambda spent should not return the same TxOut twice!
|
||||||
|
#[cfg(feature="bitcoinconsensus")]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))]
|
||||||
pub fn verify_with_flags<S, F>(&self, mut spent: S, flags: F) -> Result<(), script::Error>
|
pub fn verify_with_flags<S, F>(&self, mut spent: S, flags: F) -> Result<(), script::Error>
|
||||||
where S: FnMut(&OutPoint) -> Option<TxOut>, F : Into<u32> {
|
where S: FnMut(&OutPoint) -> Option<TxOut>, F : Into<u32> {
|
||||||
let tx = encode::serialize(&*self);
|
let tx = encode::serialize(&*self);
|
||||||
|
|
|
@ -50,8 +50,8 @@ const MAX_BITS_REGTEST: Uint256 = Uint256([
|
||||||
0x7fffff0000000000u64,
|
0x7fffff0000000000u64,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
/// Parameters that influence chain consensus.
|
/// Parameters that influence chain consensus.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub struct Params {
|
pub struct Params {
|
||||||
/// Network for which parameters are valid.
|
/// Network for which parameters are valid.
|
||||||
pub network: Network,
|
pub network: Network,
|
||||||
|
|
|
@ -49,38 +49,38 @@ macro_rules! impl_consensus_encoding {
|
||||||
macro_rules! impl_array_newtype {
|
macro_rules! impl_array_newtype {
|
||||||
($thing:ident, $ty:ty, $len:expr) => {
|
($thing:ident, $ty:ty, $len:expr) => {
|
||||||
impl $thing {
|
impl $thing {
|
||||||
#[inline]
|
|
||||||
/// Converts the object to a raw pointer
|
/// Converts the object to a raw pointer
|
||||||
|
#[inline]
|
||||||
pub fn as_ptr(&self) -> *const $ty {
|
pub fn as_ptr(&self) -> *const $ty {
|
||||||
let &$thing(ref dat) = self;
|
let &$thing(ref dat) = self;
|
||||||
dat.as_ptr()
|
dat.as_ptr()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Converts the object to a mutable raw pointer
|
/// Converts the object to a mutable raw pointer
|
||||||
|
#[inline]
|
||||||
pub fn as_mut_ptr(&mut self) -> *mut $ty {
|
pub fn as_mut_ptr(&mut self) -> *mut $ty {
|
||||||
let &mut $thing(ref mut dat) = self;
|
let &mut $thing(ref mut dat) = self;
|
||||||
dat.as_mut_ptr()
|
dat.as_mut_ptr()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Returns the length of the object as an array
|
/// Returns the length of the object as an array
|
||||||
|
#[inline]
|
||||||
pub fn len(&self) -> usize { $len }
|
pub fn len(&self) -> usize { $len }
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Returns whether the object, as an array, is empty. Always false.
|
/// Returns whether the object, as an array, is empty. Always false.
|
||||||
|
#[inline]
|
||||||
pub fn is_empty(&self) -> bool { false }
|
pub fn is_empty(&self) -> bool { false }
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Returns the underlying bytes.
|
/// Returns the underlying bytes.
|
||||||
|
#[inline]
|
||||||
pub fn as_bytes(&self) -> &[$ty; $len] { &self.0 }
|
pub fn as_bytes(&self) -> &[$ty; $len] { &self.0 }
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Returns the underlying bytes.
|
/// Returns the underlying bytes.
|
||||||
|
#[inline]
|
||||||
pub fn to_bytes(&self) -> [$ty; $len] { self.0.clone() }
|
pub fn to_bytes(&self) -> [$ty; $len] { self.0.clone() }
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Returns the underlying bytes.
|
/// Returns the underlying bytes.
|
||||||
|
#[inline]
|
||||||
pub fn into_bytes(self) -> [$ty; $len] { self.0 }
|
pub fn into_bytes(self) -> [$ty; $len] { self.0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,8 +118,8 @@ impl fmt::Display for CommandStringError {
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl ::std::error::Error for CommandStringError { }
|
impl ::std::error::Error for CommandStringError { }
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
||||||
/// A Network message
|
/// A Network message
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct RawNetworkMessage {
|
pub struct RawNetworkMessage {
|
||||||
/// Magic bytes to identify the network these messages are meant for
|
/// Magic bytes to identify the network these messages are meant for
|
||||||
pub magic: u32,
|
pub magic: u32,
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
|
|
||||||
use hash_types::{BlockHash, FilterHash, FilterHeader};
|
use hash_types::{BlockHash, FilterHash, FilterHeader};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
|
||||||
/// getcfilters message
|
/// getcfilters message
|
||||||
|
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||||
pub struct GetCFilters {
|
pub struct GetCFilters {
|
||||||
/// Filter type for which headers are requested
|
/// Filter type for which headers are requested
|
||||||
pub filter_type: u8,
|
pub filter_type: u8,
|
||||||
|
@ -17,8 +17,8 @@ pub struct GetCFilters {
|
||||||
}
|
}
|
||||||
impl_consensus_encoding!(GetCFilters, filter_type, start_height, stop_hash);
|
impl_consensus_encoding!(GetCFilters, filter_type, start_height, stop_hash);
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
|
||||||
/// cfilter message
|
/// cfilter message
|
||||||
|
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||||
pub struct CFilter {
|
pub struct CFilter {
|
||||||
/// Byte identifying the type of filter being returned
|
/// Byte identifying the type of filter being returned
|
||||||
pub filter_type: u8,
|
pub filter_type: u8,
|
||||||
|
@ -29,8 +29,8 @@ pub struct CFilter {
|
||||||
}
|
}
|
||||||
impl_consensus_encoding!(CFilter, filter_type, block_hash, filter);
|
impl_consensus_encoding!(CFilter, filter_type, block_hash, filter);
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
|
||||||
/// getcfheaders message
|
/// getcfheaders message
|
||||||
|
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||||
pub struct GetCFHeaders {
|
pub struct GetCFHeaders {
|
||||||
/// Byte identifying the type of filter being returned
|
/// Byte identifying the type of filter being returned
|
||||||
pub filter_type: u8,
|
pub filter_type: u8,
|
||||||
|
@ -41,8 +41,8 @@ pub struct GetCFHeaders {
|
||||||
}
|
}
|
||||||
impl_consensus_encoding!(GetCFHeaders, filter_type, start_height, stop_hash);
|
impl_consensus_encoding!(GetCFHeaders, filter_type, start_height, stop_hash);
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
|
||||||
/// cfheaders message
|
/// cfheaders message
|
||||||
|
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||||
pub struct CFHeaders {
|
pub struct CFHeaders {
|
||||||
/// Filter type for which headers are requested
|
/// Filter type for which headers are requested
|
||||||
pub filter_type: u8,
|
pub filter_type: u8,
|
||||||
|
@ -55,8 +55,8 @@ pub struct CFHeaders {
|
||||||
}
|
}
|
||||||
impl_consensus_encoding!(CFHeaders, filter_type, stop_hash, previous_filter_header, filter_hashes);
|
impl_consensus_encoding!(CFHeaders, filter_type, stop_hash, previous_filter_header, filter_hashes);
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
|
||||||
/// getcfcheckpt message
|
/// getcfcheckpt message
|
||||||
|
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||||
pub struct GetCFCheckpt {
|
pub struct GetCFCheckpt {
|
||||||
/// Filter type for which headers are requested
|
/// Filter type for which headers are requested
|
||||||
pub filter_type: u8,
|
pub filter_type: u8,
|
||||||
|
@ -65,8 +65,8 @@ pub struct GetCFCheckpt {
|
||||||
}
|
}
|
||||||
impl_consensus_encoding!(GetCFCheckpt, filter_type, stop_hash);
|
impl_consensus_encoding!(GetCFCheckpt, filter_type, stop_hash);
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
|
||||||
/// cfcheckpt message
|
/// cfcheckpt message
|
||||||
|
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||||
pub struct CFCheckpt {
|
pub struct CFCheckpt {
|
||||||
/// Filter type for which headers are requested
|
/// Filter type for which headers are requested
|
||||||
pub filter_type: u8,
|
pub filter_type: u8,
|
||||||
|
|
|
@ -528,8 +528,8 @@ impl<'a> fmt::Display for AddressEncoding<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
/// A Bitcoin address.
|
/// A Bitcoin address.
|
||||||
|
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct Address {
|
pub struct Address {
|
||||||
/// The type of the address.
|
/// The type of the address.
|
||||||
pub payload: Payload,
|
pub payload: Payload,
|
||||||
|
|
|
@ -171,8 +171,8 @@ impl FromStr for PublicKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
|
||||||
/// A Bitcoin ECDSA private key
|
/// A Bitcoin ECDSA private key
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
pub struct PrivateKey {
|
pub struct PrivateKey {
|
||||||
/// Whether this private key should be serialized as compressed
|
/// Whether this private key should be serialized as compressed
|
||||||
pub compressed: bool,
|
pub compressed: bool,
|
||||||
|
|
|
@ -175,17 +175,17 @@ mod message_signing {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert a signature from base64 encoding.
|
||||||
#[cfg(feature = "base64")]
|
#[cfg(feature = "base64")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "base64")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "base64")))]
|
||||||
/// Convert a signature from base64 encoding.
|
|
||||||
pub fn from_base64(s: &str) -> Result<MessageSignature, MessageSignatureError> {
|
pub fn from_base64(s: &str) -> Result<MessageSignature, MessageSignatureError> {
|
||||||
let bytes = ::base64::decode(s).map_err(|_| MessageSignatureError::InvalidBase64)?;
|
let bytes = ::base64::decode(s).map_err(|_| MessageSignatureError::InvalidBase64)?;
|
||||||
MessageSignature::from_slice(&bytes)
|
MessageSignature::from_slice(&bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert to base64 encoding.
|
||||||
#[cfg(feature = "base64")]
|
#[cfg(feature = "base64")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "base64")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "base64")))]
|
||||||
/// Convert to base64 encoding.
|
|
||||||
pub fn to_base64(&self) -> String {
|
pub fn to_base64(&self) -> String {
|
||||||
::base64::encode(&self.serialize()[..])
|
::base64::encode(&self.serialize()[..])
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,8 @@ use util::psbt::raw;
|
||||||
use hashes;
|
use hashes;
|
||||||
use util::bip32::ExtendedPubKey;
|
use util::bip32::ExtendedPubKey;
|
||||||
|
|
||||||
|
/// Enum for marking psbt hash error.
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||||
/// Enum for marking psbt hash error
|
|
||||||
pub enum PsbtHash {
|
pub enum PsbtHash {
|
||||||
Ripemd,
|
Ripemd,
|
||||||
Sha256,
|
Sha256,
|
||||||
|
|
|
@ -718,8 +718,8 @@ impl From<io::Error> for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The `Annex` struct is a slice wrapper enforcing first byte to be `0x50`.
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
/// The `Annex` struct is a slice wrapper enforcing first byte to be `0x50`
|
|
||||||
pub struct Annex<'a>(&'a [u8]);
|
pub struct Annex<'a>(&'a [u8]);
|
||||||
|
|
||||||
impl<'a> Annex<'a> {
|
impl<'a> Annex<'a> {
|
||||||
|
|
|
@ -505,9 +505,8 @@ macro_rules! construct_uint {
|
||||||
construct_uint!(Uint256, 4);
|
construct_uint!(Uint256, 4);
|
||||||
construct_uint!(Uint128, 2);
|
construct_uint!(Uint128, 2);
|
||||||
|
|
||||||
/// Invalid slice length
|
/// Invalid slice length.
|
||||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
|
||||||
/// Invalid slice length
|
|
||||||
pub struct ParseLengthError {
|
pub struct ParseLengthError {
|
||||||
/// The length of the slice de-facto
|
/// The length of the slice de-facto
|
||||||
pub actual: usize,
|
pub actual: usize,
|
||||||
|
|
Loading…
Reference in New Issue