Add `tx` message, along with `Transaction`, `Transaction(In|Out)put`, and `OutPoint` types

This commit is contained in:
Deirdre Connolly 2019-09-18 15:57:06 -04:00 committed by Deirdre Connolly
parent e0cd099487
commit 46984cbb27
2 changed files with 86 additions and 7 deletions

View File

@ -6,7 +6,7 @@ pub struct Sha256dChecksum(pub [u8; 4]);
impl<'a> From<&'a [u8]> for Sha256dChecksum { impl<'a> From<&'a [u8]> for Sha256dChecksum {
fn from(bytes: &'a [u8]) -> Self { fn from(bytes: &'a [u8]) -> Self {
use sha2::{Sha256, Digest}; use sha2::{Digest, Sha256};
let hash1 = Sha256::digest(bytes); let hash1 = Sha256::digest(bytes);
let hash2 = Sha256::digest(&hash1); let hash2 = Sha256::digest(&hash1);
let mut checksum = [0u8; 4]; let mut checksum = [0u8; 4];
@ -47,6 +47,7 @@ pub enum InventoryType {
/// message. See /// message. See
/// [BIP-152](https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki) /// [BIP-152](https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki)
/// for more info. /// for more info.
// XXX We may not need this, pzec does not.
MsgCmpctBlock = 0x04, MsgCmpctBlock = 0x04,
} }
@ -54,6 +55,74 @@ pub enum InventoryType {
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct InventoryVector(pub InventoryType, pub [u8; 32]); pub struct InventoryVector(pub InventoryType, pub [u8; 32]);
/// OutPoint
///
/// A particular transaction output reference.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct OutPoint {
/// The hash of the referenced transaction.
pub hash: [u8; 32],
/// The index of the specific output in the transaction. The first output is 0, etc.
pub index: u32,
}
/// Transaction Input
// `Copy` cannot be implemented for `Vec<u8>`
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct TransactionInput {
/// The previous output transaction reference.
pub previous_output: OutPoint,
/// Computational Script for confirming transaction authorization.
// XXX pzec uses Bytes https://docs.rs/bytes/0.4.12/bytes/
pub signature_script: Vec<u8>,
/// Transaction version as defined by the sender. Intended for
/// "replacement" of transactions when information is updated
/// before inclusion into a block.
pub sequence: u32,
}
/// Transaction Output
// `Copy` cannot be implemented for `Vec<u8>`
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct TransactionOutput {
/// Transaction value.
// At https://en.bitcoin.it/wiki/Protocol_documentation#tx, this is an i64.
pub value: u64,
/// Usually contains the public key as a Bitcoin script setting up
/// conditions to claim this output.
pub pk_script: Vec<u8>,
}
/// Transaction Input
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Transaction {
/// Transaction data format version (note, this is signed).
pub version: i32,
/// A list of 1 or more transaction inputs or sources for coins.
pub tx_in: Vec<TransactionInput>,
/// A list of 1 or more transaction outputs or destinations for coins.
pub tx_out: Vec<TransactionOutput>,
/// The block number or timestamp at which this transaction is unlocked:
///
/// |Value |Description |
/// |------------|----------------------------------------------------|
/// |0 |Not locked (default) |
/// |< 500000000 |Block number at which this transaction is unlocked |
/// |>= 500000000|UNIX timestamp at which this transaction is unlocked|
///
/// If all `TransactionInput`s have final (0xffffffff) sequence
/// numbers, then lock_time is irrelevant. Otherwise, the
/// transaction may not be added to a block until after `lock_time`.
pub lock_time: u32,
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View File

@ -2,14 +2,14 @@
use std::io; use std::io;
use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt}; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use chrono::{DateTime, TimeZone, Utc}; use chrono::{DateTime, TimeZone, Utc};
use zebra_chain::{ use zebra_chain::{
serialization::{ serialization::{
ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize, ZcashSerialize, ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize, ZcashSerialize,
}, },
types::{BlockHeight, Sha256dChecksum}, types::{BlockHeight, Sha256dChecksum, Transaction},
}; };
use crate::meta_addr::MetaAddr; use crate::meta_addr::MetaAddr;
@ -200,7 +200,16 @@ pub enum Message {
/// A `tx` message. /// A `tx` message.
/// ///
/// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#tx) /// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#tx)
Tx {/* XXX add fields */}, // `flag` is not included (it's optional), and therefore
// `tx_witnesses` aren't either, as they go if `flag` goes.
Tx {
/// Transaction data format version (note, this is signed).
version: Version,
/// The `Transaction` type itself.
// XXX Is this ~aesthetic~?
transaction: Transaction,
},
/// A `mempool` message. /// A `mempool` message.
/// ///
@ -327,6 +336,7 @@ impl Message {
} }
/// Try to read `self` from the given `reader`. /// Try to read `self` from the given `reader`.
#[allow(dead_code)]
fn try_read<R: io::Read>( fn try_read<R: io::Read>(
_reader: R, _reader: R,
_magic: Magic, _magic: Magic,
@ -343,8 +353,8 @@ impl Message {
fn write_body<W: io::Write>( fn write_body<W: io::Write>(
&self, &self,
mut writer: W, mut writer: W,
m: Magic, _m: Magic,
v: Version, _v: Version,
) -> Result<(), SerializationError> { ) -> Result<(), SerializationError> {
use Message::*; use Message::*;
match *self { match *self {