Skip to content
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

Replace u64 with Amount type in TxOut #599

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/blockdata/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use blockdata::transaction::{OutPoint, Transaction, TxOut, TxIn};
use blockdata::block::{Block, BlockHeader};
use network::constants::Network;
use util::uint::Uint256;
use Amount;

/// The maximum allowable sequence number
pub const MAX_SEQUENCE: u32 = 0xFFFFFFFF;
Expand Down Expand Up @@ -88,7 +89,7 @@ fn bitcoin_genesis_tx() -> Transaction {
.push_opcode(opcodes::all::OP_CHECKSIG)
.into_script();
ret.output.push(TxOut {
value: 50 * COIN_VALUE,
value: Amount::from_sat(50 * COIN_VALUE),
script_pubkey: out_script
});

Expand Down Expand Up @@ -166,6 +167,7 @@ mod test {
use consensus::encode::serialize;
use blockdata::constants::{genesis_block, bitcoin_genesis_tx};
use blockdata::constants::{MAX_SEQUENCE, COIN_VALUE};
use Amount;

#[test]
fn bitcoin_genesis_first_transaction() {
Expand All @@ -182,7 +184,7 @@ mod test {
assert_eq!(gen.output.len(), 1);
assert_eq!(serialize(&gen.output[0].script_pubkey),
Vec::from_hex("434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac").unwrap());
assert_eq!(gen.output[0].value, 50 * COIN_VALUE);
assert_eq!(gen.output[0].value, Amount::from_sat(50 * COIN_VALUE));
assert_eq!(gen.lock_time, 0);

assert_eq!(format!("{:x}", gen.wtxid()),
Expand Down
6 changes: 3 additions & 3 deletions src/blockdata/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,8 @@ impl Script {

#[cfg(feature="bitcoinconsensus")]
/// Shorthand for [Self::verify_with_flags] with flag [bitcoinconsensus::VERIFY_ALL]
pub fn verify (&self, index: usize, amount: u64, spending: &[u8]) -> Result<(), Error> {
self.verify_with_flags(index, ::Amount::from_sat(amount), spending, ::bitcoinconsensus::VERIFY_ALL)
pub fn verify (&self, index: usize, amount: ::Amount, spending: &[u8]) -> Result<(), Error> {
self.verify_with_flags(index, amount, spending, ::bitcoinconsensus::VERIFY_ALL)
}

#[cfg(feature="bitcoinconsensus")]
Expand Down Expand Up @@ -1250,7 +1250,7 @@ mod test {
// a random segwit transaction from the blockchain using native segwit
let spent = Builder::from(Vec::from_hex("0020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d").unwrap()).into_script();
let spending = Vec::from_hex("010000000001011f97548fbbe7a0db7588a66e18d803d0089315aa7d4cc28360b6ec50ef36718a0100000000ffffffff02df1776000000000017a9146c002a686959067f4866b8fb493ad7970290ab728757d29f0000000000220020701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d04004730440220565d170eed95ff95027a69b313758450ba84a01224e1f7f130dda46e94d13f8602207bdd20e307f062594022f12ed5017bbf4a055a06aea91c10110a0e3bb23117fc014730440220647d2dc5b15f60bc37dc42618a370b2a1490293f9e5c8464f53ec4fe1dfe067302203598773895b4b16d37485cbe21b337f4e4b650739880098c592553add7dd4355016952210375e00eb72e29da82b89367947f29ef34afb75e8654f6ea368e0acdfd92976b7c2103a1b26313f430c4b15bb1fdce663207659d8cac749a0e53d70eff01874496feff2103c96d495bfdd5ba4145e3e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053ae00000000").unwrap();
spent.verify(0, 18393430, spending.as_slice()).unwrap();
spent.verify(0, ::Amount::from_sat(18393430), spending.as_slice()).unwrap();
}

#[test]
Expand Down
9 changes: 5 additions & 4 deletions src/blockdata/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use blockdata::script::Script;
use consensus::{encode, Decodable, Encodable};
use consensus::encode::MAX_VEC_SIZE;
use hash_types::{SigHash, Txid, Wtxid};
use VarInt;
use ::{VarInt, Amount};

/// A reference to a transaction output
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
Expand Down Expand Up @@ -211,15 +211,16 @@ impl Default for TxIn {
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct TxOut {
/// The value of the output, in satoshis
pub value: u64,
#[cfg_attr(feature = "serde", serde(with="::util::amount::serde::as_sat"))]
pub value: Amount,
/// The script which must satisfy for the output to be spent
pub script_pubkey: Script
}

// This is used as a "null txout" in consensus signing code
impl Default for TxOut {
fn default() -> TxOut {
TxOut { value: 0xffffffffffffffff, script_pubkey: Script::new() }
TxOut { value: Amount::from_sat(0xffffffffffffffff), script_pubkey: Script::new() }
}
}

Expand Down Expand Up @@ -479,7 +480,7 @@ impl Transaction {
let flags: u32 = flags.into();
for (idx, input) in self.input.iter().enumerate() {
if let Some(output) = spent(&input.previous_output) {
output.script_pubkey.verify_with_flags(idx, ::Amount::from_sat(output.value), tx.as_slice(), flags)?;
output.script_pubkey.verify_with_flags(idx, output.value, tx.as_slice(), flags)?;
} else {
return Err(script::Error::UnknownSpentOutput(input.previous_output.clone()));
}
Expand Down
14 changes: 14 additions & 0 deletions src/util/amount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
use std::default;
use std::error;
use std::fmt::{self, Write};
use std::io;
use std::ops;
use std::str::FromStr;
use std::cmp::Ordering;
use consensus::{Encodable, Decodable, encode};

/// A set of denominations in which amounts can be expressed.
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
Expand Down Expand Up @@ -446,6 +448,18 @@ impl fmt::Display for Amount {
}
}

impl Encodable for Amount {
fn consensus_encode<W: io::Write>(&self, writer: W) -> Result<usize, io::Error> {
self.0.consensus_encode(writer)
}
}

impl Decodable for Amount {
fn consensus_decode<D: io::Read>(d: D) -> Result<Self, encode::Error> {
Ok(Amount(u64::consensus_decode(d)?))
}
}

impl ops::Add for Amount {
type Output = Amount;

Expand Down
11 changes: 6 additions & 5 deletions src/util/bip143.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use consensus::{encode, Encodable};

use std::io;
use std::ops::{Deref, DerefMut};
use Amount;

/// Parts of a sighash which are common across inputs or signatures, and which are
/// sufficient (in conjunction with a private key) to sign the transaction
Expand Down Expand Up @@ -176,7 +177,7 @@ impl<R: Deref<Target=Transaction>> SigHashCache<R> {
mut writer: Write,
input_index: usize,
script_code: &Script,
value: u64,
value: Amount,
sighash_type: SigHashType,
) -> Result<(), encode::Error> {
let zero_hash = sha256d::Hash::default();
Expand Down Expand Up @@ -229,7 +230,7 @@ impl<R: Deref<Target=Transaction>> SigHashCache<R> {
&mut self,
input_index: usize,
script_code: &Script,
value: u64,
value: Amount,
sighash_type: SigHashType
) -> SigHash {
let mut enc = SigHash::engine();
Expand All @@ -247,15 +248,15 @@ impl<R: DerefMut<Target=Transaction>> SigHashCache<R> {
/// ```
/// use bitcoin::blockdata::transaction::{Transaction, SigHashType};
/// use bitcoin::util::bip143::SigHashCache;
/// use bitcoin::Script;
/// use bitcoin::{Script, Amount};
///
/// let mut tx_to_sign = Transaction { version: 2, lock_time: 0, input: Vec::new(), output: Vec::new() };
/// let input_count = tx_to_sign.input.len();
///
/// let mut sig_hasher = SigHashCache::new(&mut tx_to_sign);
/// for inp in 0..input_count {
/// let prevout_script = Script::new();
/// let _sighash = sig_hasher.signature_hash(inp, &prevout_script, 42, SigHashType::All);
/// let _sighash = sig_hasher.signature_hash(inp, &prevout_script, Amount::from_sat(42), SigHashType::All);
/// // ... sign the sighash
/// sig_hasher.access_witness(inp).push(Vec::new());
/// }
Expand Down Expand Up @@ -293,7 +294,7 @@ mod tests {
let expected_result = SigHash::from_slice(&raw_expected[..]).unwrap();
let mut cache = SigHashCache::new(&tx);
let sighash_type = SigHashType::from_u32_consensus(hash_type);
let actual_result = cache.signature_hash(input_index, &script, value, sighash_type);
let actual_result = cache.signature_hash(input_index, &script, Amount::from_sat(value), sighash_type);
assert_eq!(actual_result, expected_result);
}

Expand Down
26 changes: 14 additions & 12 deletions src/util/psbt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ mod tests {

use super::PartiallySignedTransaction;
use util::psbt::raw::ProprietaryKey;
use Amount;

#[test]
fn trivial_psbt() {
Expand Down Expand Up @@ -318,13 +319,13 @@ mod tests {
}],
output: vec![
TxOut {
value: 99999699,
value: Amount::from_sat(99999699),
script_pubkey: hex_script!(
"76a914d0c59903c5bac2868760e90fd521a4665aa7652088ac"
),
},
TxOut {
value: 100000000,
value: Amount::from_sat(100000000),
script_pubkey: hex_script!(
"a9143545e6e33b832c47050f24d3eeb93c9c03948bc787"
),
Expand Down Expand Up @@ -386,7 +387,7 @@ mod tests {
}],
output: vec![
TxOut {
value: 190303501938,
value: Amount::from_sat(190303501938),
script_pubkey: hex_script!("a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587"),
},
],
Expand Down Expand Up @@ -431,7 +432,7 @@ mod tests {
inputs: vec![Input {
non_witness_utxo: Some(tx),
witness_utxo: Some(TxOut {
value: 190303501938,
value: Amount::from_sat(190303501938),
script_pubkey: hex_script!("a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587"),
}),
sighash_type: Some("SIGHASH_SINGLE|SIGHASH_ANYONECANPAY".parse().unwrap()),
Expand Down Expand Up @@ -477,6 +478,7 @@ mod tests {
use util::psbt::map::{Map, Global, Input, Output};
use util::psbt::raw;
use util::psbt::{PartiallySignedTransaction, Error};
use Amount;

#[test]
#[should_panic(expected = "InvalidMagic")]
Expand Down Expand Up @@ -574,11 +576,11 @@ mod tests {
}],
output: vec![
TxOut {
value: 99999699,
value: Amount::from_sat(99999699),
script_pubkey: hex_script!("76a914d0c59903c5bac2868760e90fd521a4665aa7652088ac"),
},
TxOut {
value: 100000000,
value: Amount::from_sat(100000000),
script_pubkey: hex_script!("a9143545e6e33b832c47050f24d3eeb93c9c03948bc787"),
},
],
Expand Down Expand Up @@ -622,11 +624,11 @@ mod tests {
}],
output: vec![
TxOut {
value: 200000000,
value: Amount::from_sat(200000000),
script_pubkey: hex_script!("76a91485cff1097fd9e008bb34af709c62197b38978a4888ac"),
},
TxOut {
value: 190303501938,
value: Amount::from_sat(190303501938),
script_pubkey: hex_script!("a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587"),
},
],
Expand Down Expand Up @@ -807,11 +809,11 @@ mod tests {
}],
output: vec![
TxOut {
value: 99999699,
value: Amount::from_sat(99999699),
script_pubkey: hex_script!("76a914d0c59903c5bac2868760e90fd521a4665aa7652088ac"),
},
TxOut {
value: 100000000,
value: Amount::from_sat(100000000),
script_pubkey: hex_script!("a9143545e6e33b832c47050f24d3eeb93c9c03948bc787"),
},
],
Expand Down Expand Up @@ -855,11 +857,11 @@ mod tests {
}],
output: vec![
TxOut {
value: 200000000,
value: Amount::from_sat(200000000),
script_pubkey: hex_script!("76a91485cff1097fd9e008bb34af709c62197b38978a4888ac"),
},
TxOut {
value: 190303501938,
value: Amount::from_sat(190303501938),
script_pubkey: hex_script!("a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587"),
},
],
Expand Down